如何将 Dictionary<enum, bool> 双向绑定到 WPF 中的 ListView 列?

Posted

技术标签:

【中文标题】如何将 Dictionary<enum, bool> 双向绑定到 WPF 中的 ListView 列?【英文标题】:How to 2-way bind a Dictionary<enum, bool> to a ListView column in WPF? 【发布时间】:2011-07-06 17:47:16 【问题描述】:

我有一个这样的类型:

public class EffectViewModel

    public string Name  get; set; 
    public string Category  get; set; 

    public Dictionary<ShaderType, bool> ShaderSupport  get; set; 

.Name.Category 已绑定到 2 个单独的列,但 ShaderSupport 字典没有。

我不知道如何将字典双向绑定到每个 ShaderType 的单独列。我不知道这些列数是否可以动态完成,但我在 xaml 中对它们进行了硬编码,例如:

<GridViewColumn Width="60" Header="GPU" >
<GridViewColumn Width="60" Header="Pixel" >
...

但现在卡在绑定部分。有什么想法吗?

【问题讨论】:

您需要删除ShaderSupport = get; set; 中的= 【参考方案1】:
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="Binding AllEffects">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="NameColumn" />
                        <ColumnDefinition Width="Auto" SharedSizeGroup="CategoryColumn" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Binding Name" />
                    <TextBlock Text="Binding Category" Grid.Column="1" />
                </Grid>
                <ItemsControl ItemsSource="Binding ShaderSupport">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="60" />
                                </Grid.ColumnDefinitions>
                                <CheckBox Grid.Row="1" IsChecked="Binding Value, Mode=OneWay" />
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

这将创建一个没有标题的网格。为了使TwoWay 模式下的复选框绑定用您自己的类型替换字典,KeyValuePair 不允许编写Value 属性,因此不能用于TwoWay 绑定。

请注意,每个EffectVM 的字典中的所有着色器都应该以相同的顺序排列。

【讨论】:

@Joan,那么您是否真的需要一个网格,其中行代表Effects,列代表Name, Category, GPU, Pixel, etc. 没错,每个 EffectViewModel 将使用具有相同名称的适当属性填充 .Name、.Category,并且 GPU、Pixel 等列将根据每个 ShaderType 存储在 ShaderSupport 中的值。 所以模糊看起来像“模糊”“平滑” ...然后下一个效果到另一行,等等。 @Joan,重写了整个 XAML @Snowbear,现在就试试。现在可以只使用字典吗?它不会崩溃或返回编译错误,对吧?我想测试绑定,如果它读取正确,那么我将切换到我的类型进行写入。【参考方案2】:

由于字典是一个 IEnumerable,您可以绑定键和值。所说的顺序并不总是与字典一致,所以我会让我的视图模型创建一个包装器 observablecollection

<ListView ItemsSource="Binding ShaderSupport">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Width="60" Header="Key" DisplayMemberBinding="Binding Key" />
                <GridViewColumn Width="60" Header="Value" DisplayMemberBinding="Binding Value" />
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

【讨论】:

这将产生一个两列的 ListView。我相信 OP 想要多个列,每个 ShaderType 在它自己的列中。 是的,我正在尝试在另一种类型中使用 ShaderSupport,因为它用于额外的列。 你试过FrameworkElementFactory吗?它允许您以非常声明性的方式创建数据模板/控制模板。

以上是关于如何将 Dictionary<enum, bool> 双向绑定到 WPF 中的 ListView 列?的主要内容,如果未能解决你的问题,请参考以下文章

Enum 枚举转 Dictionary字典

C#在Dictionary中使用枚举作为键

Dictionary里使用struct,enum做key

C#2.0怎么将dictionary值集合 转换成List<object>,dictionary中键,值类型不定

如何将 List<Dictionary<string, byte[]> 对象添加到 Dictionary<string, byte[]> [重复]

这是啥意思:“警告:'enum A<B>'和'enum A<B>'之间的比较”?