0

我有一个DataGrid.

它里面包含一些列;2 与这个问题有关,一个是DataGridTextColumn( x:Name="varTypeColumn") 显示变量类型,另一个是DataGridTemplateColumn( x:Name="varValueColumn") 可以是 TextBox 或 ComboBox 里面。

如果varTypeColumn是 Bool 类型,varValueColumn则应显示ComboBox包含 2 项的 a:True, False. 如果varTypeColumnInt类型,varValueColumn应该显示一个允许用户输入字符串的文本框。

所以我的问题是,是否有可能做到这一点xaml?我找到了一些在代码中执行此操作的实现.cs,它尝试获取 Row 并获取 Cell,最后将 TextBox/ComboBox 实例设置为 Cell 的 Content 属性。它可以工作,但如果 DataGrid 包含大量项目(例如,超过 5000 个),则显示它非常非常慢。

下面是代码部分:

        private void InitEditors()
    {
        for (int i = 0; i < _devLinkCollectionView.Count; i++)
        {
            DataGridRow row = devLinkDataGrid.GetRow(i);
            InitEditor(row);
        }
    }

    private void InitEditor(DataGridRow row)
    {
        DevLink link = row.Item as DevLink;
        if (link != null)
        {
            if (link.HasErrors)
            {
                ToolTipService.SetShowOnDisabled(row, true);
                row.IsEnabled = false;
                return;
            }

            // Create binding first
            Binding binding = new Binding("DefaultValue")
            {
                Mode = BindingMode.TwoWay,
                UpdateSourceTrigger = UpdateSourceTrigger.LostFocus,
                Source = link
            };

            DataGridCell cell = devLinkDataGrid.GetCell(row, 4);
            switch (link.VariableType)
            {
                case CarelStandardDataType.Bool:
                    ComboBox comboBox = new ComboBox();
                    comboBox.ItemsSource = new[] {string.Empty, "TRUE", "FALSE" };

                    comboBox.SetBinding(ComboBox.SelectedValueProperty, binding);
                    cell.Content = comboBox;
                    break;

                default:
                    TextBox textBox = new TextBox();
                    textBox.Style = (Style)FindResource("TextBoxInError");
                    cell.Content = textBox;

                    binding.ValidationRules.Add(new DevLinkValidationRule(link));
                    textBox.SetBinding(TextBox.TextProperty, binding);

                    break;
            }
        }
    }
4

1 回答 1

1

也许这就是你想要的。

<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridCell}">
                        <Grid Height="21.96">
                            <ComboBox x:Name="cbCondition1">
                                <ComboBoxItem Content="1"/>
                                <ComboBoxItem Content="2"/>
                            </ComboBox>

                            <TextBox x:Name="tbCondition2" Text="text"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <!--In your case, you should use custom Converter, just return type, or maybe you'd better add typeProperty in your model-->
                            <DataTrigger Binding="{Binding TypeColumn}" Value="Int">
                                <Setter Value="Visible" TargetName="cbCondition1" Property="Visibility"/>
                                <Setter Value="Hidden" TargetName="tbCondition2" Property="Visibility"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding TypeColumn}" Value="Bool">
                                <Setter Value="Hidden" TargetName="cbCondition1" Property="Visibility"/>
                                <Setter Value="Visible" TargetName="tbCondition2" Property="Visibility"/>
                            </DataTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
        <DataGrid Margin="160,106.5,119,139" ItemsSource="{Binding Collection}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding TypeColumn}"/>
                <DataGridTemplateColumn CellStyle="{StaticResource DataGridCellStyle1}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

==================样本数据============================== =

<SampleData:SampleDataSource xmlns:SampleData="clr-namespace:Expression.Blend.SampleData.SampleDataSource">
    <SampleData:SampleDataSource.Collection>
        <SampleData:Item TypeColumn="Int" ValueColumn="Row1"/>
        <SampleData:Item TypeColumn="Bool" ValueColumn="Row2"/>
    </SampleData:SampleDataSource.Collection>
</SampleData:SampleDataSource>
于 2013-11-13T12:39:05.997 回答