当前位置: 首页> 健康> 知识 > 市场监督管理局职责范围_中央广播电视总台招聘2022_软文广告经典案例800字_新手如何找cps推广渠道

市场监督管理局职责范围_中央广播电视总台招聘2022_软文广告经典案例800字_新手如何找cps推广渠道

时间:2025/9/21 5:14:00来源:https://blog.csdn.net/weixin_44122117/article/details/147085295 浏览次数:0次
市场监督管理局职责范围_中央广播电视总台招聘2022_软文广告经典案例800字_新手如何找cps推广渠道

可以在同一层级内增删排序节点的目录树实现,效果如下:
![[gif-TreeViewEditControl.gif]]

父节点可以右击新增子节点,新增数量可选;
子节点可以右击删除自身,可以在上方/下方插入同层级节点,可以上移或下移;
排序的部分,需要同时修改数据源列表的顺序。

数据

目录树为三层级,根节点、菜单节点、详情节点;
根节点无右击事件
菜单节点右击事件为新增子节点
详情节点右击为插入、排序和删除。

//1、数据源结构定义
public class DataSource : DataSourceItem
{public List<DataSourceItem> Children { get; set; }
}
public class DataSourceItem
{public Guid UniqueId { get; set; }public string Name { get; set; }
}
//一些假数据
DataSource sys = new DataSource
{UniqueId = Guid.NewGuid()
};
DataSource Node1 = new DataSource
{UniqueId = Guid.NewGuid(),Name = "Node1",Children = new List<DataSourceItem>() {new DataSourceItem{ UniqueId = Guid.NewGuid(),Name = "node" },new DataSourceItem{ UniqueId = Guid.NewGuid(),Name = "node" },}
};//2、通用节点结构定义
public class Node
{public Guid UniqueId { get; set; }public string Name { get; set; }public Guid ParentId { get; set; }public Level Level { get; set; }
}
public enum Level
{root,menu,detail
}//3、数据源转通用节点字典
private Dictionary<DataSource, Node> nodeList = new Dictionary<DataSource, Node>();
//根节点
nodeList.Add(sys, new Node { UniqueId = sys.UniqueId, Name = "Sys", ParentId = sys.UniqueId, Level = Level.root 
});
internal Node GetRoot()
{return nodeList[sys];
}
//菜单节点
var node1 = GetNode(Node1, sys.UniqueId);
nodeList.Add(node1.Key, node1.Value);
internal Node GetMenuNodeList()
{return from a in nodeListwhere a.Value.ParentId == sys.UniqueId&& a.Value.UniqueId != sys.UniqueIdselect a.Value;
}private KeyValuePair<T, Node> GetNode<T>(T o, Guid parentid, Level level = Level.menu)
{return new KeyValuePair<T, Node>(o, new Node { UniqueId = (Guid)o.GetType().GetProperty("UniqueId").GetValue(o), Name = o.GetType().GetProperty("Name").GetValue(o).ToString(), ParentId = parentid, Level = level });
}
//详情节点
private List<Node> GetDetailNodeList(DataSource parent, Guid parentid)
{List<Node> res = new List<Node>();var list = parent.Children;foreach (var o in list){var node = GetNode(o, parentid, Level.detail);res.Add(GetNode(o, parentid, Level.detail).Value);}return res;
}
//4、VM获取子节点(菜单层和详情层)
internal IEnumerable<Node> GetChildren(Guid parentId)
{if (parentId == sys.UniqueId) return GetMenuNodeList();foreach (var a in nodeList){if (a.Value.UniqueId == parentId) return GetDetailNodeList(a.Key, parentId);}return new List<Node>();
}
//5、增加节点
internal void AddNode(Node i, Guid parentId)
{foreach (var a in nodeList){if (a.Value.UniqueId == parentId){a.Key.Children.Add(new DataSourceItem() { UniqueId = i.UniqueId, Name = i.Name });}}
}
//6、删除节点
internal void RemoveNode(Guid nodeId, Guid parentId)
{foreach (var a in nodeList){if (a.Value.UniqueId == parentId){var t = a.Key.Children.Find(_ => _.UniqueId == nodeId);if (t != null) a.Key.Children.Remove(t);}}
}
//7、插入节点
internal void InsertNode(Node i, Guid tUid, Guid parentId, bool isBefore)
{foreach (var a in nodeList){if (a.Value.UniqueId == parentId){var t = a.Key.Children.FindIndex(_ => _.UniqueId == tUid);if (t != -1) a.Key.Children.Insert(isBefore ? t : (t + 1), new DataSourceItem { UniqueId = i.UniqueId, Name = i.Name });}}
}
//8、交换节点顺序
internal void SwapNode(Guid tUid, Guid parentId, bool isBefore)
{foreach (var a in nodeList){if (a.Value.UniqueId == parentId){var t = a.Key.Children.FindIndex(_ => _.UniqueId == tUid);if (t != -1){if (isBefore && t == 0) return;if (!isBefore && t == (a.Key.Children.Count - 1)) return;int swapId = isBefore ? (t - 1) : (t + 1);var temp = a.Key.Children[swapId];a.Key.Children[swapId] = a.Key.Children[t];a.Key.Children[t] = temp;}}}
}

页面

View

其中涉及
<ContextMenu>控件绑定点击事件的实现方式
利用ItemTemplateSelector选择器实现目录树不同层级不同UI的方法

<UserControl x:Class="bueatifulApp.Components.TreeViewWithEdit.View.TreeViewWithEdit"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:bueatifulApp.Components.TreeViewWithEdit.View"xmlns:vm="clr-namespace:bueatifulApp.Components.TreeViewWithEdit.ViewModel"xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"xmlns:b ="clr-namespace:bueatifulApp.Components.TreeViewWithEdit.Behavior"xmlns:LocalTmeplate='clr-namespace:bueatifulApp.Components.TreeViewWithEdit.DataTemplates'mc:Ignorable="d" x:Name="this"><UserControl.Resources><vm:BindingProxy x:Key="Proxy" Data="{Binding}" /><LocalTmeplate:ContextMenuDataTemplateSelector x:Key="ContextMenuDataTemplateSelector"/><ContextMenu x:Key="Tree_menuNodeMenu"><MenuItem Name="Add" Command="{Binding Source={StaticResource Proxy}, Path=Data.AddNodeCommand}" CommandParameter="{Binding}"><MenuItem.Header><StackPanel Orientation="Horizontal"><Label Content="新增"/><TextBox Width="20" Text="{Binding Source={StaticResource Proxy}, Path=Data.AddCount}" Height="20" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/><Label Content="个子节点"/></StackPanel></MenuItem.Header></MenuItem></ContextMenu><ContextMenu x:Key="Tree_detailNodeMenu"><MenuItem Header="删除" Name="Delete_self" Command="{Binding Source={StaticResource Proxy}, Path=Data.DeleteNodeCommand}" CommandParameter="{Binding}"/><Separator/><MenuItem Header="在上方插入" Name="Insert_up" Command="{Binding Source={StaticResource Proxy}, Path=Data.InsertBeforeNodeCommand}" CommandParameter="{Binding}"/><MenuItem Header="在下方插入" Name="Insert_down" Command="{Binding Source={StaticResource Proxy}, Path=Data.InsertAfterNodeCommand}" CommandParameter="{Binding}"/><Separator/><MenuItem Header="上移" Name="swap_up" Command="{Binding Source={StaticResource Proxy}, Path=Data.SwapBeforeNodeCommand}" CommandParameter="{Binding}"/><MenuItem Header="下移" Name="swap_down" Command="{Binding Source={StaticResource Proxy}, Path=Data.SwapAfterNodeCommand}" CommandParameter="{Binding}"/></ContextMenu><HierarchicalDataTemplate x:Key="menuNodeTemplate" ItemsSource="{Binding Children}" DataType="{x:Type vm:MenuOrgNodeViewModel}"><StackPanel Orientation="Horizontal" ContextMenu="{StaticResource Tree_menuNodeMenu}"><Label Content="{Binding Name}"/></StackPanel></HierarchicalDataTemplate><HierarchicalDataTemplate x:Key="detailNodeTemplate" ItemsSource="{Binding Children}" DataType="{x:Type vm:DetailOrgNodeViewModel}"><StackPanel Orientation="Horizontal" ContextMenu="{StaticResource Tree_detailNodeMenu}"><Label ><Label.Content><TextBlock Text="{Binding Index,StringFormat={}[{0}号]}"/></Label.Content></Label><Label Content="{Binding Name}"/></StackPanel></HierarchicalDataTemplate><HierarchicalDataTemplate x:Key="rootNodeTemplate" ItemsSource="{Binding Children}" DataType="{x:Type vm:RootOrgNodeViewModel}"><StackPanel Orientation="Horizontal"><Label Content="{Binding Name}"/></StackPanel></HierarchicalDataTemplate></UserControl.Resources><StackPanel ><TreeView Height="365" ItemsSource="{Binding Root}" ItemTemplateSelector="{StaticResource ContextMenuDataTemplateSelector}"/></StackPanel>
</UserControl>

选择器定义

public class ContextMenuDataTemplateSelector : DataTemplateSelector
{public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container){FrameworkElement element = container as FrameworkElement;DataTemplate template = null;if (item is MenuOrgNodeViewModel){template = element.FindResource("menuNodeTemplate") as HierarchicalDataTemplate;}else if (item is RootOrgNodeViewModel){template = element.FindResource("rootNodeTemplate") as HierarchicalDataTemplate;}else if (item is DetailOrgNodeViewModel){template = element.FindResource("detailNodeTemplate") as DataTemplate;}return template;}
}

<ContextMenu>控件绑定点击事件的代理器定义

public class BindingProxy : Freezable
{protected override Freezable CreateInstanceCore(){return new BindingProxy();}public object Data{get { return (object)GetValue(DataProperty); }set { SetValue(DataProperty, value); }}public static readonly DependencyProperty DataProperty =DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

ViewModel

每个节点对应的VM,处理基本数据
public class NodeViewModel : ObservableObject
{private Guid uniqueId;private string name;private Level level;private bool isSelected;public Guid UniqueId { get => uniqueId; set => uniqueId = value; }public string Name { get => name; set => name = value; }public Level Level { get => level; set => level = value; }public bool IsSelected { get => isSelected; set => OnPropertyChanged(ref isSelected, value); }internal NodeViewModel(Node node){this.UniqueId = node.UniqueId;this.Name = node.Name;this.level = node.Level;}
}
定义每个节点的父子关系和节点操作,和层级

每次增删排序后应当重新获取子节点,才能更新到页面上

public class MenuOrgNodeViewModel : OrgNodeViewModel
{internal MenuOrgNodeViewModel(Node i, OrgNodeViewModel parent = null) : base(i, parent){}
}
public class RootOrgNodeViewModel : OrgNodeViewModel
{internal RootOrgNodeViewModel(Node i, OrgNodeViewModel parent = null) : base(i, parent){}
}
public class DetailOrgNodeViewModel : OrgNodeViewModel
{internal DetailOrgNodeViewModel(Node i, OrgNodeViewModel parent = null) : base(i, parent){}
}
public class OrgNodeViewModel : NodeViewModel
{internal OrgNodeViewModel(Node i, OrgNodeViewModel parent = null): base(i){this.parent = parent;}private ObservableCollection<OrgNodeViewModel> children;private OrgNodeViewModel parent;public ObservableCollection<OrgNodeViewModel> Children{get{if (children == null)return GetChildren();return children;}set{OnPropertyChanged(ref children, value);}}public int Index {get {return parent.Children.ToList().FindIndex(_ => _.UniqueId == this.UniqueId);}}private ObservableCollection<OrgNodeViewModel> GetChildren(){children = new ObservableCollection<OrgNodeViewModel>();foreach (Node i in TreeDataAccess.GetIns().GetChildren(this.UniqueId)){if (i.Level == Level.menu) children.Add(new MenuOrgNodeViewModel(i, this));else if (i.Level == Level.detail) children.Add(new DetailOrgNodeViewModel(i, this));}return children;}private void RefreshChildren(){Children = GetChildren();}public void AddChild(int count = 1){for (int i = 0; i < count; i++){TreeDataAccess.GetIns().AddNode(new Node { UniqueId = Guid.NewGuid(), Name = "add" + i, Level = Level.detail ,ParentId = this.UniqueId}, this.UniqueId);}RefreshChildren();}public void DeleteSelf() {TreeDataAccess.GetIns().RemoveNode(this.UniqueId,this.parent.UniqueId);this.parent.RefreshChildren();}public void InsertNode(bool isBefore) {TreeDataAccess.GetIns().InsertNode(new Node { UniqueId = Guid.NewGuid(), Name = "INSERT", Level = Level.detail, ParentId = this.parent.UniqueId }, this.UniqueId,this.parent.UniqueId, isBefore);this.parent.RefreshChildren();}public void SwapNode(bool isBefore){TreeDataAccess.GetIns().SwapNode(this.UniqueId,this.parent.UniqueId,isBefore);this.parent.RefreshChildren();}}
完整目录树的VM
public class TreeViewWithEditViewModel : ObservableObject
{private List<OrgNodeViewModel> root;public List<OrgNodeViewModel> Root{get{if (root == null){root = new List<OrgNodeViewModel>{new RootOrgNodeViewModel(TreeDataAccess.GetIns().GetRoot())};}return root;}set => OnPropertyChanged(ref root, value);}private int addCount = 1;public int AddCount{get { return addCount; }set { OnPropertyChanged(ref addCount, value); }}public TreeViewWithEditViewModel(){AddNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).AddChild(AddCount);AddCount = 1;});DeleteNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).DeleteSelf();});InsertBeforeNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).InsertNode(true);});InsertAfterNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).InsertNode(false);});SwapBeforeNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).SwapNode(true);});SwapAfterNodeCommand = new RelayCommand((o) =>{(o as OrgNodeViewModel).SwapNode(false);});}public RelayCommand AddNodeCommand { get; }public RelayCommand DeleteNodeCommand { get; }public RelayCommand InsertBeforeNodeCommand { get; }public RelayCommand InsertAfterNodeCommand { get; }public RelayCommand SwapBeforeNodeCommand { get; }public RelayCommand SwapAfterNodeCommand { get; }public RelayCommand SwapNodeCommand { get; }
}
关键字:市场监督管理局职责范围_中央广播电视总台招聘2022_软文广告经典案例800字_新手如何找cps推广渠道

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: