Composite UI Application Block 之自定义UIElement(二)

目标:让我们建立一个树形结构菜单,具体的说用一个TreeView来显示菜单。先看效果图

 

1、首先我们需要建立一个自定义的TreeView,实现单击事件。

 

namespace  CustomUIElements
{
    
public delegate void NodeClickedEvent(object sender, TreeNode nodeClicked);

    
public class ClickableTreeNode : TreeNode
    
{
        ClickableTreeView _parent 
= null;
        
public event EventHandler NodeClick;

        
private bool _needsSetup = false;
        
public bool NeedsSetup
        
{
            
get return _needsSetup; }
        }

        
public ClickableTreeNode()
            : 
base()
        
{
            _needsSetup 
= true;
        }


        
public new ClickableTreeView TreeView
        
{
            
get return _parent; }
        }


        
public void SetUp(ClickableTreeView tv)
        
{
            ClickableTreeView clickable 
= tv as ClickableTreeView;
            
if (clickable == nullthrow new Exception("The clickable tree node was added to a non-clickable tree view");

            _parent 
= clickable;
            
// register for the node clicked event, when *a* node gets clicked
            clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);

            _needsSetup 
= false;
        }


        
public ClickableTreeNode(ClickableTreeView tv) : base()
        
{
            ClickableTreeView clickable 
= tv as ClickableTreeView;
            
if (clickable == nullthrow new Exception("The clickable tree node was added to a non-clickable tree view");

            _parent 
= clickable;
            
// register for the node clicked event, when *a* node gets clicked
            clickable.NodeClicked += new NodeClickedEvent(clickable_NodeClicked);
        }


        
void clickable_NodeClicked(object sender, TreeNode nodeClicked)
        
{
           
// if the node is actually us, then fire the NodeClick event...
            if ((nodeClicked as ClickableTreeNode) == this)
            
{              
                
if (NodeClick != null)
                    NodeClick(
thisnew EventArgs());
            }
              
        }

    }


    
public class ClickableTreeView : TreeView
    
{
        
public event NodeClickedEvent NodeClicked;

        
public ClickableTreeView() : base()
        
{
            
this.MouseClick += new MouseEventHandler(ClickableTreeView_MouseClick);
        }


        
void ClickableTreeView_MouseClick(object sender, MouseEventArgs e)
        
{
            TreeViewHitTestInfo inf 
= HitTest(e.X, e.Y);
            
if (inf.Node == nullreturn// didnt click a node...

            
// we clicked a node, so notify that one was clicked...
            if (NodeClicked != null)
                NodeClicked(
this, inf.Node);
            
        }
       
    }

}

2、我们需要的是建立两个我们自己的类,分别实现IUIElementAdapterFactory和UIElementAdapter<T>。

 

  public   class  ClickableTreeViewAdapterFactory : IUIElementAdapterFactory
    
{
        
IUIElementManagerFactory Members

        
IUIElementAdapterFactory Members
    }

 

 

  public   class  ClickableTreeViewAdapter: UIElementAdapter < ClickableTreeNode >
    
{
        
private ClickableTreeView _managed = null;
        
private ClickableTreeNode _managedNode = null;
        
public ClickableTreeViewAdapter(ClickableTreeView element)
        
{
            _managed 
= element;
        }


        
public ClickableTreeViewAdapter(ClickableTreeNode node)
        
{
            _managedNode 
= node;
        }


        
protected override void Remove(ClickableTreeNode uiElement)
        
{
            
if (_managed != null)
            
{
                
if (!_managed.IsDisposed)
                
{
                    
if (_managed.Nodes.Contains(uiElement))
                        _managed.Nodes.Remove(uiElement);
                }

            }

            
else if (_managedNode != null)
            
{
                
if (!_managedNode.TreeView.IsDisposed)
                
{
                    
if (_managedNode.Nodes.Contains(uiElement))
                        _managedNode.Nodes.Remove(uiElement);
                }

            }

        }

    
        
protected override ClickableTreeNode Add(ClickableTreeNode item)
        
{
            
if (_managed != null)
            
{
                
if (item.NeedsSetup)
                    item.SetUp(_managed);
                _managed.Nodes.Add(item);
            }

            
else if (_managedNode != null)
            
{
                
if (item.NeedsSetup)
                    item.SetUp(_managedNode.TreeView);
                _managedNode.Nodes.Add(item);
            }


            
return item;
        }
        
    }

 

3、在初始化阶段注册我们自定义的界面工厂

 

         protected   override   void  AfterShellCreated()
        
{
            
base.AfterShellCreated();

            IUIElementAdapterFactoryCatalog catalog 
= RootWorkItem.Services.Get<IUIElementAdapterFactoryCatalog>();
            catalog.RegisterFactory(
new ClickableTreeViewAdapterFactory());

            
// both main menus should have their items added to the root nodes collection
            RootWorkItem.UIExtensionSites.RegisterSite(UIExtensionConstants.MAINMENU, Shell.MainNavigationTree);

            
// Load the menu structure from App.config
            UIElementBuilder.LoadFromConfig(RootWorkItem, Shell.MainNavigationTree);
        }
### 创建自定义Web UI界面的方法 #### 选择合适的工具和技术栈 为了创建高效的Web UI界面,开发者可以选择多种技术栈。对于希望实现大模型与Web应用无缝对接的应用场景,Open WebUI提供了一个理想的解决方案[^1]。该平台不仅支持快速原型设计,还允许集成复杂的机器学习模型。 #### 利用现成框架加速开发过程 利用现有的前端框架可以大大缩短开发周期并提高效率。例如,在构建交互式的AI驱动应用程序时,可以通过Web用户界面轻松创建Ollama模型,这使得添加自定义角色/代理以及定制化聊天组件变得简单快捷[^2]。这种做法有助于团队专注于核心功能而非底层架构的设计。 #### 设计阶段的重要性 在着手编码之前,清晰的需求分析至关重要。了解目标用户的期望可以帮助设计师更好地规划布局、颜色方案及其他视觉元素。对于复杂项目如跨境电商平台,则需经历更详细的策划流程——从初步构思到最终部署都不可忽视任何一个环节[^3]。 #### 动态参数配置增强灵活性 当涉及到特定业务逻辑或个性化体验时,能够灵活调整内部工作流就显得尤为重要。Flink中的DataStream API虽然主要用于处理实时数据流任务,但也展示了如何通过编程方式设定动态参数来满足不同应用场景下的特殊需求[^4]。类似地,在构建Web UI过程中引入类似的机制可以让页面更加适应多变的市场环境。 ```html <!-- 示例HTML结构 --> <div id="custom-ui"> <!-- 自定义内容区域 --> </div> <script src="./path/to/framework.js"></script> <!-- 引入所需库文件 --> ``` ```javascript // JavaScript代码片段用于初始化和管理UI状态 document.addEventListener('DOMContentLoaded', () => { const uiElement = document.getElementById('custom-ui'); function updateUI(data) { // 更新DOM节点的内容或其他属性 uiElement.innerHTML = `<p>${data.message}</p>`; } fetch('/api/data') .then(response => response.json()) .then(updateUI); }); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值