如何将数据从Dictionary绑定到xaml并使用所选对象

时间:2018-05-07 10:10:16

标签: c# wpf mvvm

CategoriesView.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>

CategoriesViewModel.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());
        }
    }
}

我的目标是:

  • <TextBlock Text="{Binding Path=Key}"/>显示Category.Name。我不 知道如何像对象一样使用Key并使用属性Name
  • 当我按下“添加值”按钮时,我想在“类别”对象中设置“CategoryId”并通过“AddValue”命令将其发送给 信使

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

  1. 使用Key.Name绑定到TextBlock
  2. 要绑定到列表框,您有两种方法:
  3. - 使用SelectedItem。您已经拥有了一个属性&#34;类别&#34;在您的viewmodel中。将该属性绑定到列表框选定项。然后,您可以在AddValue命令中使用Category.CategoryID。

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

    - 使用SelectedValue。 SelectedCategoryId应该是viewmodel上的属性。然后,您可以在AddValue命令中直接使用此属性。

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