【问题标题】:Set 2 type controls(TextBox and ComboBox ) in same DataGridTemplateColumn in XAML在 XAML 中的相同 DataGridTemplateColumn 中设置 2 个类型的控件(TextBox 和 ComboBox)
【发布时间】:2013-11-25 22:44:56
【问题描述】:

我有一个DataGrid

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

如果 varTypeColumn 是 Bool 类型,varValueColumn 应该显示一个 ComboBox,其中包含 2 个项目:TrueFalse。如果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;
            }
        }
    }

【问题讨论】:

  • 请显示您的代码/xaml

标签: wpf xaml datagrid datagridtemplatecolumn


【解决方案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>

【讨论】:

  • 谢谢,就我而言,对于类型列,我将它绑定到变量集合项的 VariableType 属性,它是一个包含 Bool、Int 的枚举(XXStandardDataType)......所以在你的代码中,如何我可以更改 DataTrigger 部分吗,谢谢
  • 对于枚举,只需从枚举的定义中复制字符串即可。例如
  • 但我将它绑定到 VariableType 属性,即 enum(XXStandardDataType) 类型。
猜你喜欢
  • 1970-01-01
  • 2015-03-08
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多