首先,即使我发现了一些类似的问题,但没有一个(到目前为止)回答了我的具体问题。
为了快速总结,我正在尝试将数据绑定(bind)到 TreeView 。这是我所拥有的:
我有一个数据库,我用它创建了一个 ADO.NET 实体数据模型。我想在 TreeView 中绑定(bind) 3 个实体:国家、部门和实体。国家(一)与实体(多个)相关联,部门(一)与实体(多个)相关联。
下面是 ADO.NET 实体数据模型为每个对象生成的代码
public partial class Country
{
public Country()
{
this.Entities = new HashSet<Entity>();
}
public int country_id { get; set; }
public string country_name { get; set; }
public virtual ICollection<Entity> Entities { get; set; }
}
public partial class Sector
{
public Sector()
{
this.Entities = new HashSet<Entity>();
}
public int sector_id { get; set; }
public string sector_name { get; set; }
public virtual ICollection<Entity> Entities { get; set; }
}
public partial class Entity
{
public Entity()
{
this.Entities_to_Indexes = new HashSet<Entities_to_Indexes>();
this.StreamParameters_to_Entities = new HashSet<StreamParameters_to_Entities>();
this.Tweets_to_Entities = new HashSet<Tweets_to_Entities>();
}
public int entity_id { get; set; }
public string entity_name { get; set; }
public int sector_id { get; set; }
public int country_id { get; set; }
public virtual Country Country { get; set; }
public virtual Sector Sector { get; set; }
public virtual ICollection<Entities_to_Indexes> Entities_to_Indexes { get; set; }
public virtual ICollection<StreamParameters_to_Entities> StreamParameters_to_Entities { get; set; }
public virtual ICollection<Tweets_to_Entities> Tweets_to_Entities { get; set; }
}
我现在想将它们绑定(bind)到 WPF 表单中的 TreeView 控件,以获得如下内容:
- 国家1
- 部门1
- 实体1
- 实体2
- Sector2
- 实体3
- 实体4
- 部门1
- 国家2
- 部门1
- 实体5
- 实体6
- 部门1
...
无论我如何寻找它,我都无法找到如何将它们直接绑定(bind)到 TreeView 中。
预先感谢您提供的任何帮助。
最佳答案
首先创建 View 模型类,如下所示:
public class CountryVm
{
public CountryVm(string name)
{
//since Name is a simple property it's better to initialize it in constructor
//because Name is neither a dependency property nor notifies about it changes.
//see DependencyProperty and INotifyPropertyChanged documentation
Name = name;
}
public string Name { get; set; }
//an observable collection notifies about any changes made in it
public ObservableCollection<SectorVm> Sectors { get { return _sectors; } }
private ObservableCollection<SectorVm> _sectors = new ObservableCollection<SectorVm>();
}
public class SectorVm
{
public SectorVm(string name)
{
Name = name;
}
public string Name { get; set; }
public ObservableCollection<EntityVm> Entities { get { return _entities; } }
private ObservableCollection<EntityVm> _entities = new ObservableCollection<EntityVm>();
}
public class EntityVm
{
public EntityVm(string name)
{
Name = name;
}
public string Name { get; set; }
}
为整个窗口(或UserControl或其他什么)创建另一个viewModel,我称之为MainVm
我实现了两个额外的依赖属性作为示例:
public class MainVm : DependencyObject
{
/// <summary>
/// Gets or sets a fully bindable value that indicates MyText
/// </summary>
public string MyText
{
get { return (string)GetValue(MyTextProperty); }
set { SetValue(MyTextProperty, value); }
}
public static readonly DependencyProperty MyTextProperty=
DependencyProperty.Register("MyText", typeof(string), typeof(MainVm),
new PropertyMetadata("default value here"));
/// <summary>
/// Gets or sets a fully bindable value that indicates MyProp
/// </summary>
public float MyProp
{
get { return (float)GetValue(MyPropProperty); }
set { SetValue(MyPropProperty, value); }
}
public static readonly DependencyProperty MyPropProperty =
DependencyProperty.Register("MyProp", typeof(float), typeof(MainVm),
new PropertyMetadata(0f,//default value (MUST be the same type as MyProp)
//property changed callback
(d, e) =>
{
var vm = (MainVm)d;
var val = (float)e.NewValue;
vm.MyText = val.ToString();
},
//coerce value callback
(d, v) =>
{
var vm = (MainVm)d;
var val = (float)v;
//prevents from having negative value
if (val < 0f) return 0f;
return v;
}));
public ObservableCollection<CountryVm> AllCountries { get { return _allCountries; } }
private ObservableCollection<CountryVm> _allCountries = new ObservableCollection<CountryVm>();
}
设置 MainVm
的实例作为DataContext
您的窗口(或 UC 或...)
public MainWindow()
{
InitializeComponent();
DataContext = new MainVm();
}
设置AllCountries
作为ItemsSource
的TreeView
。自 DataContext
是继承的,DataContext
的TreeView
是 MainVm
的同一个实例您之前指定为 DataContext
窗口的。
<TreeView ItemsSource="{Binding AllCountries}"/>
定义三个没有 KEY 的资源,以便 TreeView.ItemTemplate
根据 DataType
自动选择其中之一项目的。
<Window.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Sectors}" DataType="{x:Type vm:CountryVm}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Entities}" DataType="{x:Type vm:Sector}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type vm:Entity}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</Window.Resources>
还要将此行添加到 .xaml 代码的开头(在 Window 标记中)。您可能必须将命名空间更改为您自己的 ViewModel 的命名空间:
xmlns:vm="clr-namespace:MyWpfApplication1.Core.ViewModels;assembly=MyWpfApplication1.Core">
或者 您可以实现一个 ViewModel 而不是三个(将其称为 TreeNodeVm)
public class TreeNodeVm
{
public TreeNodeVm(string name)
{
Name = name;
}
public string Name { get; set; }
public ObservableCollection<TreeNodeVm> Children { get { return _children; } }
private ObservableCollection<TreeNodeVm> _children = new ObservableCollection<TreeNodeVm>();
}
并编写TreeView xaml代码如下:
<TreeView ItemsSource="{Binding AllCountries}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
关于c# - 将 EntityFramework 实体绑定(bind)到 TreeView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27092875/