首页 > 解决方案 > 获取 ItemsControl MVVM 中的当前项

问题描述

我在字典中填充了ItemsControl一些键列表,我建议用户映射每个键,打印在 aLabel中,并在下面的 a 中具有一些值ComboBox

最后,我必须通过 ComboBox 中的选定值来获取对应的 Label 键,以便填充字典值。

我的所有控件都以 MVVM 模式绑定到 ViewModel 属性。

<ItemsControl x:Name="icMapping"
          HorizontalAlignment="Center" MaxHeight="120"
          ItemsSource="{Binding ColumnsMapping}">

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.Template>
    <ControlTemplate>
        <ScrollViewer VerticalScrollBarVisibility="Auto">
            <ItemsPresenter/>
        </ScrollViewer>
    </ControlTemplate>
</ItemsControl.Template>

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <StackPanel HorizontalAlignment="Center" Margin="6">
            <Label x:Name="lblPropertyKey"
                   Content="{Binding ApiPropertyKey}"
                   Width="250"/>
            <ComboBox x:Name="cboxCsvHeaders"
                      Width="250"
                      ItemsSource="{Binding
                                    RelativeSource={RelativeSource Mode=FindAncestor,
                                                                    AncestorType=Window},
                                    Path=DataContext.CsvTemplateFile.CsvHeaders}"
                      SelectedItem="{Binding
                                    RelativeSource={RelativeSource Mode=FindAncestor,
                                                                    AncestorType=Window},
                                    Path=DataContext.SelectedCsvHeader, Mode=OneWayToSource}"/>
        </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>

我试图遍历.Text 中ItemsTemplate的值ItemsControl,但我在ComboBox.Text 中绑定值后填充了 .Text SelectedItem

private string selectedCsvHeader;
public string SelectedCsvHeader
{
    get => selectedCsvHeader;
    set
    {
        selectedCsvHeader = value;
        if (value != null)
        {
            var ic = this.configView.icMapping;
            for (int i = 0; i < ic.Items.Count; i++)
            {
                System.Windows.Controls.ContentPresenter cp = (System.Windows.Controls.ContentPresenter)ic.ItemContainerGenerator.ContainerFromItem(ic.Items[i]);
                System.Windows.Controls.ComboBox cbox = cp.ContentTemplate.FindName("cboxCsvHeaders", cp) as System.Windows.Controls.ComboBox;
                System.Windows.Controls.Label lbl = cp.ContentTemplate.FindName("lblPropertyKey", cp) as System.Windows.Controls.Label;

                MessageBox.Show((cbox.Text == selectedCsvHeader).ToString()); // False
            }
            FillDgPreview();
        }
        OnPropertyChanged(nameof(SelectedCsvHeader));
    }
}

我使用ItemsControl是因为我事先不知道我的字典中有多少键。(在网上搜索后) 这里有一张图片来解释

提前谢谢!

标签: c#wpfmvvm

解决方案


为了设置字典条目的值,您必须使用允许更改Value其键/值对条目的属性的字典类。

由于Dictionary<TKey,TValue>不允许这样做(因为KeyValuePair<TKey,TValue>它是不可变的),您可以编写自己的字典类,可能比此示例更复杂:

public class KeyValue
{
    public KeyValue(string key, string value = null)
    {
        Key = key;
        Value = value;
    }

    public string Key { get; }
    public string Value { get; set; }
}

public class ViewModel
{
    public List<KeyValue> Map { get; } = new List<KeyValue>();

    public List<string> Keys { get; } = new List<string>();
}

您现在将绑定该视图模型,如下所示的 XAML,其中{Binding Key}{Binding Value}使用字典条目(即Map集合元素)作为源对象。如果您使用具有不同条目类型的自定义字典类,这些绑定看起来会有所不同。

<ItemsControl ItemsSource="{Binding Map}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Key}"/>
                <ComboBox SelectedItem="{Binding Value}"
                          ItemsSource="{Binding DataContext.Keys,
                                        RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

推荐阅读