集合到布尔转换器

时间:2012-06-27 14:55:57

标签: wpf binding checkbox datatemplate

在我的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列绑定到Default集合的Products。我有另一个产品列表集合,其中只包含产品,现在我需要选中该列表包含产品的复选框。

有人可以帮我收集布尔转换器。我尽我所能但却无法把它弄好。

提前致谢。

2 个答案:

答案 0 :(得分:0)

如果你想使用价值转换器,我建议你试试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();
        }
    }
    
  • 将新创建的转换器放入Resources Window 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> ... ,它可能取决于您用于公开其他集合的特定方式(如本答案的第一步所述)。但是,它看起来可能类似于:

    {{1}}

我没有测试过这个,所以如果你对这些任务有任何问题,请告诉我,我可以帮你。

答案 1 :(得分:0)

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