【问题标题】:Collection to boolean converter集合到布尔转换器
【发布时间】:2012-06-27 14:55:57
【问题描述】:

在我的 wpf 应用程序中,我有一个如下的数据网格

                            <Custom:DataGrid x:Name="dg_nba" IsEnabled="{Binding Iseditmode}" SelectionMode="Single" ItemsSource="{Binding Products}" Style="{DynamicResource myDataGridStyle}" IsReadOnly="True" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*">
                        <Custom:DataGrid.Columns>
                            <Custom:DataGridTextColumn x:Name="dgt_nba_id" Header="Id" Binding="{Binding ID}" MaxWidth="40"/>
                            <Custom:DataGridTextColumn x:Name="dgt_nba_name" Binding="{Binding Name}" Header="Name"/>
                            <Custom:DataGridTemplateColumn x:Name="dgtc_nba_incl" Header="Include" MaxWidth="50">
                                <Custom:DataGridTemplateColumn.CellTemplate >
                                    <DataTemplate>
                                            <CheckBox HorizontalAlignment="Center" Style="{DynamicResource myCheckBoxStyle}"/>
                                    </DataTemplate>
                                </Custom:DataGridTemplateColumn.CellTemplate>
                            </Custom:DataGridTemplateColumn>
                        </Custom:DataGrid.Columns>
                    </Custom:DataGrid>

我已将 datagrid id 、 name 列与默认产品集合绑定。我有另一个产品列表集合,其中仅包含产品,现在我需要检查列表是否包含产品的复选框。

有人可以帮助我将 Collection 转换为布尔转换器。我尽了最大的努力,但无法做到正确。

提前致谢。

【问题讨论】:

  • 此外,您可能需要寻找不同的解决方案,因为 IValueConverter 只能采用一个参数,而您需要两个参数:集合和要查找的值。

标签: wpf binding checkbox datatemplate


【解决方案1】:

如果您想使用值转换器,我建议您尝试IMultiValueConverter。您可以尝试将另一个集合作为一个值传递,并将您正在寻找的 ID 作为两个不同的值传递给转换器。为了使其工作,您应该:

  • 使您可以在 XAML 中访问代码隐藏变量。您可以在此处找到有关执行此操作的一些方法的更多信息:Access codebehind variable in XAML
  • 实现IMultiValueConverter。它可能取决于您的应用程序的一些细节(例如您正在使用的集合的类型),但它可能或多或少像这样:

    class ICollectionToBoolConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                //verify if appropriate number of values is bound
                if (values != null && values.Length == 2)
                {
                    List<Product> productsList = (values[0] as List<Product>);
    
                    //if converter is used with appropriate collection type
                    if (productsList != null)
                    {
                        //if there is object ID specified to be found in the collection
                        if (values[1] != null)
                        {
                            int objectToFindId = (int)values[1];
    
                            //return information if the collection contains an item with ID specified in parameter
                            return productsList.Any(p => p.ID == objectToFindId);
                        }
                    }
                }
    
                //return false if object is not found or converter is used inappropriately
                return false;
            }
            catch
            {
                return false;
            }
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
  • 将您新创建的转换器放入ResourcesWindow(或UserControl)中DataGrid 所在的位置

    <c:ICollectionToBoolConverter x:Key="collectionToBoolConverter" />
    
  • 使用转换器绑定CheckBox,它可以取决于您用来公开其他集合的特定方式(如本答案的第一步所述)。但是,它可能看起来类似于:

    ...
    <Custom:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox HorizontalAlignment="Center" Style="{DynamicResource myCheckBoxStyle}">
                <CheckBox.IsChecked>
                    <MultiBinding Converter="{StaticResource collectionToBoolConverter}">
                        <Binding  ElementName="layoutRoot" Path="Parent.MyCollectionName" />
                        <Binding Path="ID" />
                    </MultiBinding>
                </CheckBox.IsChecked>
            </CheckBox>
        </DataTemplate>
    </Custom:DataGridTemplateColumn.CellTemplate>
    ...
    

我没有对此进行测试,所以如果您对这些任务有任何问题,请告诉我,我会尽力帮助您。

【讨论】:

  • 谢谢。我写了一个类似的转换器,但在绑定时遇到了一些问题。我发现你的控制器更简单,我使用了它。
  • 我可以把它做成双向绑定吗?如果是这样,我应该使用 convertback 来实现吗?
  • 我现在坚持使用转换,因为我以两种方式使用它。此转换器 / 是否可以转换回?
  • 您希望它如何工作?我想您希望它将项目添加(/删除)到(/从)列表中。请记住,在转换回来的情况下,您有一个参数值(在这种情况下为布尔值),并且应该将其转换回两个值以作为绑定的对象返回。如果您想动态更新集合,我建议您处理CheckBoxClick 事件并将适当的产品添加到那里的列表中。我想您应该能够将 ID 绑定到 Tag 属性以确定在处理程序中添加/删除哪个产品。
【解决方案2】:

在这种情况下,您最好在 ViewModel(您要绑定的对象)中计算 IsChecked 值。如果您从 VM 公开描述性属性(只读:HasDesiredProduct),则可以在从集合中添加/删除项目时调整该属性,并让复选框以只读方式反映内部逻辑。

【讨论】:

    猜你喜欢
    • 2014-03-23
    • 2014-05-12
    • 2012-10-26
    • 2014-01-26
    • 2012-09-03
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多