【问题标题】:WPF DataGrid: Making the column type dynamic for every rowWPF DataGrid:使每一行的列类型动态化
【发布时间】:2019-08-15 06:27:23
【问题描述】:

我有一个 WPF DataGrid。在一个专栏中,我目前显示了一个ComboBox,其值为enum。代码如下所示:

<DataGridTemplateColumn Header="Solution">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
             <ComboBox ItemsSource="{utils:Enumerate {x:Type EnumSolution}}" SelectedItem="{Binding Solution, Converter={StaticResource EnumToStringConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
   </DataGridTemplateColumn.CellEditingTemplate>
   <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
             <ComboBox ItemsSource="{utils:Enumerate {x:Type EnumSolution}}" SelectedItem="{Binding Solution, Converter={StaticResource EnumToStringConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

但我不想为所有行显示 ComboBox。我只想为特定行显示它,而只为其他行显示一个文本。有没有可能是这样的:

【问题讨论】:

  • 使用CellTemplateSelector
  • 看起来很有希望。我会测试一下。谢谢

标签: c# wpf mvvm datagrid


【解决方案1】:

还有一种方法:

将内容控件放入 DataGrid:

<DataGrid Name="Test" AutoGenerateColumns="False"  ItemsSource="{Binding MyList}">
        <DataGrid.Columns >
            <DataGridTemplateColumn Header="Name">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding MyControl}"  />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

然后在你的类中创建内容属性:

public class MyClass
{
    public string Name { get; set; }
    public List<string> MyList { get; set; }

    public Control MyControl
    {
        get
        {
            return GetControlForName();
        }
    }

    Control GetControlForName()
    {
        if (Name == "textbox")
        {
            var textBox = new TextBox();
            Binding binding = new Binding(nameof(Name));
            binding.Source = this;
            textBox.SetBinding(TextBox.TextProperty, binding);
            return textBox;
        }
        else if (Name == "combobox")
        {
            var comboBox = new ComboBox();
            comboBox.ItemsSource = MyList;
            return comboBox;
        }
        {
            return null;
        }
    }
}

结果如下:

 public List<MyClass> MyList { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        MyList = new List<MyClass>()
        {
            new MyClass() { Name = "textbox" },
            new MyClass() { Name = "combobox", MyList = new List<string> { "1", "2" } },
            new MyClass() { Name = "textbox" },
            new MyClass() { Name = "combobox", MyList = new List<string> { "1", "2" } }
        };
    }

【讨论】:

    【解决方案2】:

    您可以使用CellTemplateSelector

    首先创建一个代表你的选择器的类——逻辑什么时候选择什么模板:

    public class MyCellTemplateSelector : DataTemplateSelector
    {
        public DataTemplate SolutionTextBlockTemplate { get; set; }
        public DataTemplate SolutionComboboxTemplate { get; set; }
    
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var diff = item as YourDatGridRowObjectType;
            if(diff != null)
            {
                if (<your condition on when to choose this template>))
                    return SolutionTextBlockTemplate;
                return SolutionComboboxTemplate;
            }
            return null;
        }        
    }
    

    在包含 DataGrid 的控件中,您为此定义资源 - 模板的实际外观:

    <Window.Resources>
        <DataTemplate x:Key="SolutionTextBlockTemplate">
            <TextBlock Text="{Binding Solution}" />
        </DataTemplate>
        <DataTemplate x:Key="SolutionComboBoxTemplate">
            <ComboBox ItemsSource="{utils:Enumerate {x:Type connectToEcomp:EnumSolution}}" SelectedItem="{Binding Solution, Converter={StaticResource EnumToStringConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate> 
    </Window.Resources>
    

    DataGrid 本身中,您可以像这样使用这些模板:

    <DataGridTemplateColumn Header="Solution" >
        <DataGridTemplateColumn.CellTemplateSelector>
            <local:MyCellTemplateSelector 
                 SolutionTextBlockTemplate="{StaticResource SolutionTextBlockTemplate}" 
                 SolutionComboboxTemplate="{StaticResource SolutionComboBoxTemplate}" />
        </DataGridTemplateColumn.CellTemplateSelector>  
    </DataGridTemplateColumn>
    

    【讨论】:

      猜你喜欢
      • 2017-07-19
      • 1970-01-01
      • 2011-03-05
      • 2011-02-25
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      相关资源
      最近更新 更多