使用数据绑定到的更新的字典内容更新组合框内容

时间:2019-01-04 21:36:54

标签: xaml dictionary combobox mainwindow

我有一个组合框,其显示和值路径已成功绑定到字典。

唯一的问题是XAML不会填充实际的字典,直到这些框在上面的xaml中放好为止。

因此,组合框不显示任何内容,因为制作组合框时字典甚至不存在。

在加载主窗口之后,是否有一种方法可以更新组合框,这样我就不必对布局进行太多修改,就可以让它恢复放置后的外观实例化字典对象后的组合框xaml?

我觉得这是最简单的方法。

1 个答案:

答案 0 :(得分:0)

很高兴看到您要尝试做的事的样本,但我会竭尽所能回答您所提供的内容。

需要使组合框知道绑定到的集合已更新,并在发生这种情况时刷新其视觉表示。集合本身负责通知绑定到它的控件集合已更改。词典没有这种能力来通知绑定到它们的控件。

您应该考虑使用ObservableCollection。假设您使用的是视图模型,则看起来像这样:

tidyverse

在XAML中,您将在绑定中指定MyItems。创建收藏夹和更改收藏夹成员时,ComboBox都会更新。

library(tidyverse)
df %>%
   filter(date > (special_date - 30))

这假定视图的数据上下文已设置为MyViewModel的实例。

已更新为支持复合馆藏绑定

这是将组合集合与组合框一起使用的示例。首先,视图。在这里,我创建了一个绑定到复合集合的ComboBox。我还具有一个文本框,该文本框显示组合框中的所选项目,还有两个列表,显示视图模型上两个ObservableCollections的内容。最后,有一个按钮可以将新项目添加到组合视图中的一个集合中。

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<MyComboBoxItem> _myItems;
    public ObservableCollection<MyComboBoxItem> MyItems
    {
        get => _myItems;
        set { _myItems = value; OnPropertyChanged(); }
    }
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void InitializeCollection()
    {
        MyItems = new ObservableCollection<MyComboBoxItem>();
        MyItems.Add(new MyComboBoxItem() { Text = "Hello" });
    }
}

以下是该视图的代码。它在构造函数中初始化视图的DataContext,并具有按钮的click事件处理程序。

<ComboBox ItemsSource="{Binding MyItems}"/>

现在,视图模型。首先,包含项目的类:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">

    <Window.Resources>
        <DataTemplate x:Key="ComboBoxItemDataTemplate"
                      DataType="local:MyComboBoxItem">

                <TextBlock Margin="4"
                           Text="{Binding Text}" />
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <StackPanel VerticalAlignment="Center"
                    HorizontalAlignment="Center">
            <StackPanel Margin="4"
                        Orientation="Horizontal"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Center">
                <ComboBox Margin="4"
                          Width="220"
                          Height="28"
                          ItemsSource="{Binding ComboBoxItems}"
                          SelectedItem="{Binding SelectedComboBoxItem, Mode=TwoWay}"
                          ItemTemplate="{StaticResource ComboBoxDataTemplate}" />
                <TextBlock Margin="4"
                           Width="220"
                           Text="{Binding SelectedComboBoxItem.Text}" />
            </StackPanel>

            <TextBlock Margin="4"
                       Text="Invariable Items" />
            <ListBox Margin="4"
                     ItemsSource="{Binding InvariableItems}"
                     ItemTemplate="{StaticResource ComboBoxDataTemplate}" />
            <TextBlock Margin="4"
                       Text="Variable Items" />
            <ListBox Margin="4"
                     ItemsSource="{Binding VariableItems}"
                     ItemTemplate="{StaticResource ComboBoxDataTemplate}" />
            <Button Width="80"
                    Click="OnAddVariableItem">Add</Button>
        </StackPanel>
    </Grid>
</Window>

接下来,视图模型本身。我们定义了两个可观察的集合,一个用于永远不变的事物,另一个用于经常变化的事物。然后,我们为视图创建一个复合集合。当我们向变量集合中添加新项目时,我们只需重新创建复合集合即可。

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        var dc = new MyViewModel();
        DataContext = dc;

    }

    private void OnAddVariableItem(object sender, RoutedEventArgs e)
    {
        if (DataContext is MyViewModel viewModel)
        {
            viewModel.AddVariableItem();
        }
    }
}