lightswitch 添加 TreeView 控件
代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <UserControl xmlns:sdk= "http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class= "LightSwitchApplication.TreeViewControl.DepartmentTreeViewControl" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d= "http://schemas.microsoft.com/expression/blend/2008" xmlns:local= "clr-namespace:LightSwitchApplication.TreeViewControl" xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable= "d" d:DesignHeight= "300" d:DesignWidth= "400" > <UserControl.Resources> <local:EntityCollectionValueConverter x:Key= "EntityCollectionValueConverter" /> </UserControl.Resources> <Grid x:Name= "LayoutRoot" Background= "White" > <StackPanel Orientation= "Horizontal" > <sdk:TreeView Name= "treeViewControl" SelectedItemChanged= "treeViewControl_SelectedItemChanged" ItemsSource= "{Binding Screen.DepartmentTree}" > <sdk:TreeView.ItemTemplate> <sdk:HierarchicalDataTemplate ItemsSource="{Binding Converter={StaticResource EntityCollectionValueConverter}, ConverterParameter=Children}"> <StackPanel Orientation= "Horizontal" > <!--<CheckBox IsChecked= "{Binding IsSelected, Mode=TwoWay}" />--> <TextBlock Text= "{Binding Path=Name, Mode=TwoWay}" Margin= "5,0" Width= "74" /> </StackPanel> </sdk:HierarchicalDataTemplate> </sdk:TreeView.ItemTemplate> </sdk:TreeView> </StackPanel> </Grid> </UserControl> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | using Microsoft.LightSwitch.Framework.Client; using Microsoft.LightSwitch.Presentation; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace LightSwitchApplication.TreeViewControl { public partial class DepartmentTreeViewControl : UserControl { public DepartmentTreeViewControl() { InitializeComponent(); } private void treeViewControl_SelectedItemChanged( object sender, RoutedPropertyChangedEventArgs< object > e) { var selectItem = (LightSwitchApplication.Department)treeViewControl.SelectedItem; var type1 = selectItem.GetType(); var context = (IContentItem) this .DataContext; var screen = context.Screen; var data = (VisualCollection<LightSwitchApplication.Department>)screen.Details.Properties[ "DepartmentTree" ].Value; data.SelectedItem = selectItem; //data.text= selectItem.Details.Properties["Id"].Value; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | using Microsoft.LightSwitch; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace LightSwitchApplication.TreeViewControl { public class EntityCollectionValueConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string strErrorMessage = "Converter parameter should be set to the property name that will serve as source of data" ; IEntityObject entity = value as IEntityObject; if (entity == null ) throw new ArgumentException( "The converter should be using an entity object" ); string sourcePropertyName = parameter as string ; if ( string .IsNullOrWhiteSpace(sourcePropertyName)) throw new ArgumentException(strErrorMessage); // Enumerate the source property using logic dispatcher // and prepare the collection of entities that the control will bind to var entities = new ObservableCollection<IEntityObject>(); var temporaryEntites = new List<IEntityObject>(); entity.Details.Dispatcher.BeginInvoke( delegate { IEntityCollection eCollection = entity.Details.Properties[sourcePropertyName].Value as IEntityCollection; if (eCollection == null ) { Debug.Assert( false , "The property " + sourcePropertyName + " is not an entity collection" ); return ; } // Now we are on the logic thread. We cannot just stuff the observable collection // with entities because the collection will immediately raise Changed events // and this will result in invalid cross-thread access. So we'll use a temporary collection // and copy the entites again on the UI thread foreach (IEntityObject e in eCollection) { temporaryEntites.Add(e); } Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke( delegate { // I wish ObservableCollection had an AddRange() method... foreach (IEntityObject e in temporaryEntites) { entities.Add(e); } }); }); return entities; } public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } } |
片段2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | public partial class CategoriesListDetail { private TreeView treeView = null ; partial void CategoriesListDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo) { // Write your code here. } partial void CategoriesListDetail_Created() { // Write your code here. this .P_Name = "" ; this .RootNode.Load(); this .FindControl( "TreeViewControl" ).ControlAvailable += ((o, e) => { treeView = e.Control as TreeView; treeView.BorderThickness = new Thickness(1); if (treeView.Items.Count == 0) { foreach ( var item in this .RootNode) { TreeViewItem rootItem = new TreeViewItem() { Header = item.Name, Tag = item.Id }; treeView.Items.Add(rootItem); } treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler< object >(TreeViewItem_SelectedItemChanged); } }); } private void TreeViewItem_SelectedItemChanged( object sender, RoutedPropertyChangedEventArgs< object > e) { var parentItem = e.NewValue as TreeViewItem; this .P_Name = ( string )parentItem.Header; this .p_id = ( int )parentItem.Tag; ///when collection is refreshed the event SelectedNodeEmployees_Changed is hooked up ///do not use Load method to avoid caching this .SelectedChildrenNodes.Refresh(); } partial void SelectedChildrenNodes_Changed(NotifyCollectionChangedEventArgs e) { if (treeView != null ) { Dispatchers.Main.BeginInvoke(() => { var parentItem = treeView.SelectedItem as TreeViewItem; if (parentItem != null ) { if (parentItem.Items.Count == 0 && this .SelectedChildrenNodes.Count() > 0) { foreach ( var item in this .SelectedChildrenNodes) //.Where(act => act.Title != "???") { TreeViewItem newChildItem = new TreeViewItem() { Header = item.Name, Tag = item.Id }; parentItem.Items.Add(newChildItem); } } } }); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix