首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将ViewModel绑定到分层TreeView到选定的值

将ViewModel绑定到分层TreeView到选定的值
EN

Stack Overflow用户
提问于 2022-03-27 11:29:47
回答 1查看 91关注 0票数 0

我正试图按照此链接实现一个国家名单。基本上它有一个id:有3个级别数据的国家。

我使用这个类按需要显示树视图:

代码语言:javascript
运行
复制
using System.Collections.ObjectModel;

namespace ckd.Library
{
  /// <summary>
  /// implementation of the hierarchical data from the ABS SACC 2016
  /// @link https://www.abs.gov.au/statistics/classifications/standard-australian-classification-countries-sacc/latest-release 
  /// </summary>
  public static class Sacc2016
  {
    public static  ObservableCollection<MajorGroup> Countries { get; set; }

    static Sacc2016()
    {
      Countries = new ObservableCollection<MajorGroup>();

      var majorGroup1 = new MajorGroup(1, "OCEANIA AND ANTARCTICA");

      var minorGroup11 = new MinorGroup(11, "Australia (includes External Territories)");
      var minorGroup12 = new MinorGroup(12, "New Zealand");
      var minorGroup13 = new MinorGroup(13, "Melanesia");

      minorGroup11.Countries.Add(new Country(1101, "Australia"));
      minorGroup11.Countries.Add(new Country(1102, "Norfolk Island"));
      minorGroup11.Countries.Add(new Country(1199, "Australian External Territories, nec"));
      minorGroup12.Countries.Add(new Country(1201, "New Zealand"));
      minorGroup13.Countries.Add(new Country(1301, "New Caledonia"));

      Countries.Add(majorGroup1);
     
    }
  }

  public class MajorGroup
  {
    public MajorGroup(int id, string name)
    {
      Id = id;
      Name = name;
      MinorGroups = new ObservableCollection<MinorGroup>();
    }

    public int                              Id          { get; set; }
    public string                           Name        { get; set; }
    public ObservableCollection<MinorGroup> MinorGroups { get; set; }
  }

  public class MinorGroup
  {
    public MinorGroup(int id, string name)
    {
      Id = id;
      Name = name;
      Countries = new ObservableCollection<Country>();
    }

    public int                           Id        { get; set; }
    public string                        Name      { get; set; }
    public ObservableCollection<Country> Countries { get; set; }
  }

  public class Country
  {
    public Country(int id, string name)
    {
      Id = id;
      Name = name;
    }

    public int    Id   { get; set; }
    public string Name { get; set; }
  }
}

我的ViewModel实现了INotifyPropertyChanged,部分是:

代码语言:javascript
运行
复制
    private int? _CountryOfBirth;
    public int? CountryOfBirth
    {
      get => _CountryOfBirth;
      set => SetProperty(ref _CountryOfBirth, value);
    }
    public ObservableCollection<MajorGroup>                CountriesObservableCollection   { get; private set; }
    void ViewModelConstructor(){
       ...
       CountriesObservableCollection = Sacc2016.Countries;
       ...
    }

最后,xaml部分是:

代码语言:javascript
运行
复制
<TreeView x:Name="CountriesTreeView" HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch" 
                      ItemsSource="{Binding CountriesObservableCollection}"
                      SelectedValue="{Binding CountryOfBirth, Mode=OneWayToSource }"
                      SelectedValuePath="Id"
                      >  
                <TreeView.ItemTemplate>  
                    <HierarchicalDataTemplate ItemsSource="{Binding MinorGroups}" DataType="{x:Type library:MajorGroup}">  
                        <Label Content="{Binding Name}"/>  
                        <HierarchicalDataTemplate.ItemTemplate>  
                            <HierarchicalDataTemplate ItemsSource="{Binding Countries}" DataType="{x:Type library:MinorGroup}">  
                                <Label Content="{Binding Name}"/>  
                                <HierarchicalDataTemplate.ItemTemplate>  
                                    <DataTemplate DataType="{x:Type library:Country}">  
                                        <Label Content="{Binding Name}"/>  
                                    </DataTemplate>  
                                </HierarchicalDataTemplate.ItemTemplate>  
                            </HierarchicalDataTemplate>  
                        </HierarchicalDataTemplate.ItemTemplate>  
                    </HierarchicalDataTemplate>  
                </TreeView.ItemTemplate>  
            </TreeView>  

这个xaml给出了一个错误:View.xaml(260, 23): [MC3065] 'SelectedValue' property is read-only and cannot be set from markup. Line 260 Position 23.删除selectedValue显示:

因此,我的问题是,如何将Id字段(从MajorGroup、MinorGroup和Country)链接到视图模型中的CountryOfBirth属性?

EN

回答 1

Stack Overflow用户

发布于 2022-03-27 15:56:36

有许多解决办法。一个简单的MVVM就绪解决方案是处理TreeView.SelectedItemChanged事件以设置一个本地依赖属性,您可以绑定到视图模型类:

MainWindow.xaml.cs

代码语言:javascript
运行
复制
partial class MainWindow : Window
{
  public static readonly DependencyProperty SelectedTreeItemProperty = DependencyProperty.Register(
    "SelectedTreeItem", 
    typeof(object), 
    typeof(MainWindow), 
    new PropertyMetadata(default));

  public object SelectedTreeItem
  {
    get => (object)GetValue(SelectedTreeItemProperty);
    set => SetValue(SelectedTreeItemProperty, value); 
  }

  public MainWindow()
  {
    InitializeComponent();
    this.DataContext = new MainViewModel();
  }

  private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
  {
    var treeView = sender as TreeView;
    this.SelectedTreeItem = treeView.SelectedItem;
  }
}

MainWindow.xaml

代码语言:javascript
运行
复制
<Window>
  <Window.Resources>
    <Style TargetType="local:MainWindow">
      <Setter Property="SelectedTreeItem"
              Value="{Binding SelectedDataModel, Mode=OneWayToSource}" />
    </Style> 
  </Window.Resources>

  <TreeView SelectedItemChanged="TreeView_SelectedItemChanged" />
</Window>

MainViewModel.cs

代码语言:javascript
运行
复制
class MainViewModel : INotifyPropertyChanged
{
  public object SelectedDataModel { get; set; }
}

或者,您也可以将逻辑从MainWindow.xaml.cs移动到附加行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71635917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档