Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF treeview和datagrid选择已更改_C#_Wpf - Fatal编程技术网

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));
    }


  }