WPF DataGrid控件中某一列根据另一个文本列的值显示相应的模板控件

之前做项目的时候需要实现这样一个功能。WPF DataGrid有两列,一列为"更新状态”列,一列为"值"列,如果"更新状态"列的值为“固定值更新”,则"值"列显示下拉列表框控件。如果"更新状态"列的值为"序列号更新",则"值"列显示按钮控件。如果"更新状态"列的值为“文本值更新”,则"值"列显示文本控件。实现如下:

1、模型类

public class UpdateDataModel:INotifyPropertyChanged
    {
        public string Name { get; set; }

        public string UpdateStatus { get; set; }

        public string Value { get; set; }

        public List<string> ValueList { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
模型类

2、实现模板选择器

public class ValueSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            DataTemplate dt = new DataTemplate();
            if (item != null && item is UpdateDataModel)
            {
                UpdateDataModel model = item as UpdateDataModel;
                Window window = Application.Current.MainWindow;
                if (model.UpdateStatus.Equals("固定值更新"))
                {
                    //实例化下拉列表框控件
                    FrameworkElementFactory comboBox = new FrameworkElementFactory(typeof(ComboBox));
                    comboBox.SetBinding(ComboBox.ItemsSourceProperty, new Binding()
                    {
                        Path = new PropertyPath("ValueList"),
                        Mode = BindingMode.TwoWay,
                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                    });
                    comboBox.SetValue(ComboBox.MarginProperty, new Thickness(5));
                    dt.VisualTree = comboBox;

                }
                else if (model.UpdateStatus.Equals("序列号更新"))
                {
                    //实例化按钮控件
                    FrameworkElementFactory button = new FrameworkElementFactory(typeof(Button));
                    button.SetBinding(Button.ContentProperty, new Binding()
                    {
                        Path = new PropertyPath("Value"),
                        Mode = BindingMode.TwoWay,
                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                    });
                    button.SetValue(Button.ForegroundProperty, Brushes.Black);
                    button.SetValue(Button.HorizontalAlignmentProperty, HorizontalAlignment.Center);
                    //button.SetValue(Button.PaddingProperty, new Thickness(5, 0, 0, 0));
                    //button.SetValue(Button.BackgroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#218aff")));
                    dt.VisualTree = button;
                }
                else
                {
                    //实例化文本控件
                    FrameworkElementFactory txtBox = new FrameworkElementFactory(typeof(TextBox));
                    txtBox.SetBinding(TextBox.TextProperty, new Binding()
                    {
                        Path = new PropertyPath("Value"),
                        Mode = BindingMode.TwoWay,
                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                    });
                    txtBox.SetValue(TextBox.ForegroundProperty, Brushes.White);
                    txtBox.SetValue(TextBox.BackgroundProperty, new SolidColorBrush(Colors.Transparent));
                    dt.VisualTree = txtBox;
                }
            }
            return dt;
        }
    }
模板选择器

3、界面

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:u="clr-namespace:WpfApplication1" Width="500" Height="350"
        Title="MainWindow" Loaded="Window_Loaded">
    <Window.Resources>
        <u:ValueSelector x:Key="selector"></u:ValueSelector>
    </Window.Resources>
    <Grid>
        <DataGrid Name="datagrid" Background="Transparent" Foreground="Black" SelectionMode="Single" BorderThickness="0"
                  AutoGenerateColumns="False" RowHeaderWidth="0" CanUserAddRows="False" AlternationCount="2" MinWidth="420"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled" GridLinesVisibility="None" HeadersVisibility="Column">
            <DataGrid.Columns>
                <DataGridTextColumn Header="名称" Width="3*" Binding="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"></DataGridTextColumn>
                <DataGridTextColumn Header="更新状态"  Width="3*" Binding="{Binding Path=UpdateStatus,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True"></DataGridTextColumn>
                <DataGridTemplateColumn Header="值" Width="4*" CellTemplateSelector="{StaticResource selector}" IsReadOnly="True"></DataGridTemplateColumn>
            </DataGrid.Columns>
            
        </DataGrid>
    </Grid>
</Window>
MainWindow.xaml

4、后台代码

/// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            List<string> ValueList = new List<string>() { "项1", "项2", "项3", "项4" };
            List<UpdateDataModel> list = new List<UpdateDataModel>() { 
                new UpdateDataModel(){Name="测试数据1",UpdateStatus="固定值更新",ValueList=ValueList},
                new UpdateDataModel(){Name="测试数据2",UpdateStatus="序列号更新",Value="设 置"},
                new UpdateDataModel(){Name="测试数据3",UpdateStatus="文本更新"}
            };
            datagrid.ItemsSource = list;
        }
    }
MainWindow.xaml.cs

5、运行效果

示例代码:http://files.cnblogs.com/files/xiaomianyang/WpfApplication1.rar

原文地址:https://www.cnblogs.com/xiaomianyang/p/6419326.html