首页 > 解决方案 > 如何将字典中的数据绑定到 xaml 并使用选定的对象

问题描述

类别视图.xaml

<local:AllViewBase x:Class="Test.View.Tab.CategoriesView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Test.View.Abstract"
             mc:Ignorable="d">

    <UserControl.Resources>
        <ResourceDictionary Source="pack://application:,,,/Content/Style/MainWindowDictionary.xaml"/>
    </UserControl.Resources>

    <Grid>
        <ListBox ItemsSource="{Binding Path=dcCategory}" SelectedItem="{Binding Path=Category,Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Orientation="Horizontal" >
                            <Button Content="Add Value" Command="{Binding Path=DataContext.AddValue, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>
                            <TextBlock Text="{Binding Path=Key}"/>
                        </StackPanel>
                        <ListBox ItemsSource="{Binding Path=Value}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid> 
</local:AllViewBase>

类别ViewModel.cs

namespace Test.ViewModel.Tab
{
    public class CategoriesViewModel : AllViewModel<CategoryValueAllView>
    {
        private BaseCommand _AddValue;

        private Category _Category;
        public Category Category
        {
            get
            {
                return _Category;
            }
            set
            {
                if (_Category != value)
                {
                    _Category = value;
                    OnPropertyChanged(() => Category);
                }
            }
        }

        private Dictionary<Category, List<string>> _dcCategory;
        public Dictionary<Category, List<string>> dcCategory
        {
            get
            {
                if (_dcCategory == null) LoadDictionary();
                return _dcCategory;
            }
            set
            {
                if (_dcCategory != value)
                {
                    _dcCategory = value;
                    OnPropertyChanged(() => dcCategory);
                }
            }
        }

        public ICommand AddValue
        {
            get
            {
                if (_AddValue == null)
                {
                    _AddValue = new BaseCommand(() => Messenger.Default.Send(CategoryValueCode.AddValue + "," + Category.CategoryId));
                }
                return _AddValue;
            }
        }

        public void LoadDictionary()
        {
            dcCategory = (from k in db.Category join w in db.CategoryVal on k.CategoryId equals w.CategoryId select new CategoryValueAllView { Category = w.Category, Val = w.Val }).GroupBy(x => x.Category).ToDictionary(grp => grp.Key, grp => grp.Select(obj => obj.Val).ToList());
        }
    }
}

我的目标是:

早些时候,我使用字符串 category.name 而不是字典键的类别对象。然后<TextBlock Text="{Binding Path=Key}"/>显示正确的名称,但毕竟我无法在单击按钮后将“category.name”传递给“AddValue”命令以按名称获取 id 并通过 Messenger 设置数据。

通过名称获取 id 也是可以接受的,不需要将 Category 对象作为键

尽管我想学习它,但我无法忍受一个显示出这样问题的例子

谢谢!

标签: c#wpfmvvm

解决方案


  1. 使用 Key.Name 绑定到 TextBlock
  2. 要绑定到列表框,您有两种方法:

- 使用 SelectedItem。您的视图模型中已经有一个属性“类别”。将该属性绑定到列表框选定项。然后,您可以在 AddValue 命令中使用 Category.CategoryID。

<ListBox ItemsSource = "{Binding Path = dcCategory}" SelectedItem = "{Binding Path = Category, Mode = TwoWay}">

- 使用选定值。SelectedCategoryId 应该是视图模型上的一个属性。然后,您可以在 AddValue 命令中直接使用此属性。

<ListBox ItemsSource = "{Binding Path = dcCategory}" SelectedValuePath = "CategoryId" SelectedValue = "{Binding Path = SelectedCategoryId, Mode = TwoWay}">

推荐阅读