C# WPF treeview和datagrid选择已更改
我正在使用C# WPF treeview和datagrid选择已更改,c#,wpf,C#,Wpf,我正在使用Treeview和DataGrid处理这个WPF项目 左侧是一个树形结构,数据网格中的一些文档显示在右侧。 如果我们在树状视图中更改所选项目,datagrid显示应该会更改。 所有文档都应显示全部,以此类推。 有人能给我指出正确的方向吗?我在winforms中使用了一些视图模型。 在WPF中这样做似乎很难。我只是在学习WPF。以下是我迄今为止所做的工作。现在,我在树中引入的部分是一些帮助或网站 <Grid ShowGridLines="False">
Treeview
和DataGrid
处理这个WPF项目
左侧是一个树形结构,数据网格中的一些文档显示在右侧。
如果我们在树状视图中更改所选项目,datagrid显示应该会更改。
所有文档都应显示全部,以此类推。
有人能给我指出正确的方向吗?我在winforms中使用了一些视图模型。
在WPF中这样做似乎很难。我只是在学习WPF。以下是我迄今为止所做的工作。现在,我在树中引入的部分是一些帮助或网站
<Grid ShowGridLines="False">
<DataGrid Name="DataGrid1" AutoGenerateColumns="False" AlternatingRowBackground="AliceBlue">
<DataGrid.Columns>
<DataGridTextColumn Header="Document Type Name" Binding="{Binding DocumentType.DocumentTypeName}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Status" Binding="{Binding Name}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Description" Binding="{Binding Description}" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Header="Type" Binding="{Binding Type}" IsReadOnly="True"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</StackPanel>
由于默认的TreeView不支持SelectedItem上的绑定,因此您必须执行一个难看的解决方法。对Treeview进行子类化并首先使其可绑定:
public class TreeViewA : TreeView {
public new static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeViewA), new FrameworkPropertyMetadata(null, OnSelectedItemChanged));
public TreeViewA() {
base.SelectedItemChanged += this.OnTreeViewSelectedItemChanged;
this.ItemContainerGenerator.StatusChanged += this.ItemContainerGeneratorOnStatusChanged;
}
public new object SelectedItem {
get {
return this.GetValue(SelectedItemProperty);
}
set {
this.SetValue(SelectedItemProperty, value);
}
}
private void ItemContainerGeneratorOnStatusChanged(object sender, EventArgs eventArgs) {
if (this.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
return;
if (this.SelectedItem != null) {
this.VisualSelectItem();
}
}
private void VisualSelectItem() {
var xx = (TreeViewItem)this.ItemContainerGenerator.ContainerFromItem(this.SelectedItem);
if (xx == null)
return;
xx.IsSelected = true;
xx.BringIntoView();
}
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
this.SelectedItem = e.NewValue;
}
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
if (e.NewValue != null) {
(sender as TreeViewA)?.VisualSelectItem();
}
}
}
我的示例窗口后面的代码:
public partial class Window1 : INotifyPropertyChanged {
public Window1() {
InitializeComponent();
this._docs.Add(new Document { Name = "Doc1", Type = "docx", Description = "Important Doc", DocumentTypeName = "Word-Document" });
this._docs.Add(new Document { Name = "Doc2", Type = "xlsx", Description = "Important Calculation", DocumentTypeName = "Excel-Document" });
this._docs.Add(new Document { Name = "Doc3", Type = "pdf", Description = "Important Contract", DocumentTypeName = "Pdf-Document" });
this.DataContext = this;
}
public Document SelectedDocument {
get {
return this._selectedDocument;
}
set {
if (Equals(value, this._selectedDocument))
return;
this._selectedDocument = value;
this.SubDocuments.Clear();
this.SubDocuments.Add(value);
this.OnPropertyChanged();
}
}
public ObservableCollection<Document> SubDocuments
{
get { return this._subDocuments; }
set
{
if (Equals(value, this._subDocuments)) return;
this._subDocuments = value;
this.OnPropertyChanged();
}
}
private readonly ObservableCollection<Document> _docs = new ObservableCollection<Document>();
private Document _selectedDocument;
private ObservableCollection<Document> _subDocuments = new ObservableCollection<Document>();
public ObservableCollection<Document> Documents => this._docs;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
公共部分类窗口1:INotifyPropertyChanged{
公共窗口1(){
初始化组件();
添加(新文档{Name=“Doc1”,Type=“docx”,Description=“maintal Doc”,DocumentTypeName=“Word Document”});
此._docs.Add(新文档{Name=“Doc2”,Type=“xlsx”,Description=“重要计算”,DocumentTypeName=“Excel文档”});
新增(新文件{Name=“Doc3”,Type=“pdf”,Description=“重要合同”,DocumentTypeName=“pdf文件”});
this.DataContext=this;
}
公共文件精选文件{
得到{
返回此。\u选择的文档;
}
设置{
if(等于(值,此.\u所选文档))
返回;
这是。\ u选择的文档=值;
此文件为.SubDocuments.Clear();
本.子文件.增加(价值);
this.OnPropertyChanged();
}
}
公开收集子文档
{
获取{返回此。\子文档;}
设置
{
if(等于(值,此._子文档))返回;
此._子文档=值;
this.OnPropertyChanged();
}
}
私有只读ObservableCollection _docs=新ObservableCollection();
私人文件(选择的文件);;
私有ObservableCollection_子文档=新ObservableCollection();
公共可观察收集文件=>此文件;
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null){
this.PropertyChanged?.Invoke(this,newpropertychangedeventargs(propertyName));
}
}
结束
这段代码应该为您提供一个想法,以及如何做到这一点。它肯定不同于您的实际对象和实现。但是,既然你说你只需要朝正确的方向推一下,这可能会给你一个跳跃式的开始
注意
我使用代码隐藏实现了这一点,但是模型没有实现INotifyPropertyChanged
,因为在本例中这并不重要
希望这能有所帮助。与您的说法相反,在WPF中执行此操作将非常简单。你的麻烦在哪里?你被困在哪里?你已经试过什么了?@lokusking:编辑了我的问题
public class Document {
public string Name {
get; set;
}
public string DocumentTypeName {
get; set;
}
public string Description {
get; set;
}
public string Type {
get; set;
}
}
public partial class Window1 : INotifyPropertyChanged {
public Window1() {
InitializeComponent();
this._docs.Add(new Document { Name = "Doc1", Type = "docx", Description = "Important Doc", DocumentTypeName = "Word-Document" });
this._docs.Add(new Document { Name = "Doc2", Type = "xlsx", Description = "Important Calculation", DocumentTypeName = "Excel-Document" });
this._docs.Add(new Document { Name = "Doc3", Type = "pdf", Description = "Important Contract", DocumentTypeName = "Pdf-Document" });
this.DataContext = this;
}
public Document SelectedDocument {
get {
return this._selectedDocument;
}
set {
if (Equals(value, this._selectedDocument))
return;
this._selectedDocument = value;
this.SubDocuments.Clear();
this.SubDocuments.Add(value);
this.OnPropertyChanged();
}
}
public ObservableCollection<Document> SubDocuments
{
get { return this._subDocuments; }
set
{
if (Equals(value, this._subDocuments)) return;
this._subDocuments = value;
this.OnPropertyChanged();
}
}
private readonly ObservableCollection<Document> _docs = new ObservableCollection<Document>();
private Document _selectedDocument;
private ObservableCollection<Document> _subDocuments = new ObservableCollection<Document>();
public ObservableCollection<Document> Documents => this._docs;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}