代码之家  ›  专栏  ›  技术社区  ›  Sebastian Hoelzl

WPF DataGrid复选框列样式

  •  -1
  • Sebastian Hoelzl  · 技术社区  · 7 年前

    我想创建一个具有(m x n)单元格的数据报。每个单元应包含一个复选框。 现在,如果选中一个单元格的复选框,我要将此特定单元格的背景色更改为红色。

    我的问题是我不知道运行时会有多少行和列。

    有人能帮我举个例子吗?或者给我一个提示从哪里开始?我在网上搜索了好几天都没有成功:(

    谢谢!

    塞巴斯蒂安

    2 回复  |  直到 7 年前
        1
  •  2
  •   mm8    7 年前

    可以创建表示行和单元格的类型,并在视图中以编程方式创建一些单元格模板和单元格样式。请参考以下示例。

    公共类行 { 公共单元格[]单元格get;set; } 公共类单元格:InotifyPropertiesChanged { 检查私人布尔值; 公共福利被检查 { 获取返回_ischecked; 设置IsChecked=value;notifyPropertyChanged(); } 公共事件propertychangedeventhandler propertychanged; private void notifypropertychanged([callermembername]string propertyname=“)=> 属性已更改?.invoke(this,new propertychangedeventargs(propertyname)); } 公共类视图模型 { 公共视图模型() { 常量int n=10; 常量int m=5; list<row>rows=新建列表<row>(); 对于(int i=0;i<n;++i) { rows.add(新行单元格=新单元格[m]); 对于(int j=0;j<m;++j) { 行[i].cells[j]=new cell(); } } 行=行; } public IEnumerable<row>行get;set; } < /代码>

    查看:

    public-partial-class-mainwindow:window
    {
    公共主窗口()
    {
    初始化组件();
    window2viewModel viewModel=new window2viewModel();
    row row=viewModel.rows.firstOrDefault();
    如果(行)!=空)
    {
    datatemplate datatemplate=datagrid.resources[“celltemplate”]作为datatemplate;
    对于(int i=0;i<row.cells.length;+i)
    datagrid.columns.add(new datagridTemplateColumn()cellTemplate=createCellTemplate(i),cellstyle=createCellStyle(i));
    }
    dataContext=viewModel;
    }
    
    私有静态数据模板createCellTemplate(int index)
    {
    const-string xaml=“<datatemplate xmlns=\”http://schemas.microsoft.com/winfx/2006/xaml/presentation“xmlns:x=\”http://schemas.microsoft.com/winfx/2006/xaml\”x:key=\“celltemplate\”><复选框被选中\“绑定单元格[0]。被选中,updateSourceTrigger=propertyChanged \“content=\”check“/>/datatemplate>”
    将xamlreader.parse(string.format(xaml,index))返回为datatemplate;
    }
    
    私有静态样式CreateCellStyle(int index)
    {
    const string xaml=“<style targetType=\”dataGridCell\“xmlns=\”http://schemas.microsoft.com/winfx/2006/xaml/presentation\“xmlns:x=\”http://schemas.microsoft.com/winfx/2006/xaml\“>”。+
    “<style.triggers>”“+
    “<dataTrigger binding=\”绑定单元格[0]。已检查\”value=\“true\”>“”+
    “<setter property=\”background\“value=\”red\“/>“”+
    “</datatrigger>”。+
    “</style.triggers>”“+
    “</style>”;
    
    将xamlreader.parse(string.format(xaml,index))作为样式返回;
    }
    }
    < /代码> 
    
    

    xaml:

    <datagrid x:name=“datagrid”itemssource=“binding rows”autogenerateColumns=“false”canUserAddRows=“false”/>
    < /代码> 
    
    

    以下示例。

    public class Row
    {
        public Cell[] Cells { get; set; }
    }
    
    public class Cell : INotifyPropertyChanged
    {
        private bool _isChecked;
        public bool IsChecked
        {
            get { return _isChecked; }
            set { _isChecked = value; NotifyPropertyChanged(); }
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    
    public class ViewModel
    {
        public ViewModel()
        {
            const int n = 10;
            const int m = 5;
    
            List<Row> rows = new List<Row>();
            for (int i = 0; i < n; ++i)
            {
                rows.Add(new Row { Cells = new Cell[m] });
                for (int j = 0; j < m; ++j)
                {
                    rows[i].Cells[j] = new Cell();
                }
            }
            Rows = rows;
        }
    
        public IEnumerable<Row> Rows { get; set; }
    }
    

    观点:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Window2ViewModel viewModel = new Window2ViewModel();
            Row row = viewModel.Rows.FirstOrDefault();
            if (row != null)
            {
                DataTemplate dataTemplate = dataGrid.Resources["cellTemplate"] as DataTemplate;
                for (int i = 0; i < row.Cells.Length; ++i)
                    dataGrid.Columns.Add(new DataGridTemplateColumn() { CellTemplate = CreateCellTemplate(i), CellStyle = CreateCellStyle(i) });
            }
            DataContext = viewModel;
        }
    
        private static DataTemplate CreateCellTemplate(int index)
        {
            const string Xaml = " <DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" x:Key=\"cellTemplate\"><CheckBox IsChecked=\"{{Binding Cells[{0}].IsChecked, UpdateSourceTrigger=PropertyChanged}}\" Content=\"Check\" /></DataTemplate>";
            return XamlReader.Parse(string.Format(Xaml, index)) as DataTemplate;
        }
    
        private static Style CreateCellStyle(int index)
        {
            const string Xaml = "<Style TargetType=\"DataGridCell\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"> " +
                                "     <Style.Triggers> " +
                                "       <DataTrigger Binding=\"{{Binding Cells[{0}].IsChecked}}\" Value=\"True\"> " +
                                "        <Setter Property=\"Background\" Value=\"Red\" /> " +
                                "       </DataTrigger> " +
                                "     </Style.Triggers> " +
                                "</Style>";
    
            return XamlReader.Parse(string.Format(Xaml, index)) as Style;
        }
    }
    

    XAML:

    <DataGrid x:Name="dataGrid" ItemsSource="{Binding Rows}" AutoGenerateColumns="False" CanUserAddRows="False" />
    

    enter image description here

        2
  •  0
  •   Sebastian Hoelzl    7 年前

    这个例子还没有完成,但是演示了我现在如何解决它:

    此示例不使用DataGrid。布局s*cks:d

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            List<KeyGroup> keygroups = new List<KeyGroup>();
            ColumnHeaderRow headerrow = new ColumnHeaderRow(keygroups);
            for (int i = 0; i <= 10; i++)
            {
                keygroups.Add(new KeyGroup("Col " + i.ToString()));
            }
    
            VStack.Children.Add(headerrow);
    
            for (int i = 0; i <= 10; i++){
                List<CellObject> cells = new List<CellObject>();
                for (int j = 0; j <= 10; j++)
                {
                    if (i % 2 == 0) cells.Add(new CellObject(i, j, true));
                    else cells.Add(new CellObject(i, j, false));
                }
                RowObject newrow = new RowObject(cells);
                VStack.Children.Add(newrow);
            }
        }
    }
    
    public class RowObject : StackPanel
    {
        public List<CellObject> cells { get; set; }
    
        public RowObject(List<CellObject> cells)
        {
            this.cells = cells;
            this.Orientation = Orientation.Horizontal;
            foreach(CellObject cell in this.cells)
            {
                this.Children.Add(cell);
            }
        }
    }
    
    public class CellObject : CheckBox
    {
        public int Row { get; set; }
        public int Column { get; set; }
        public Int64 Id { get; set; }
        public bool Value { get { return this.IsChecked.Value; } set { this.IsChecked = value; } }
        public Int64 IdLck { get; set; }
        public Int64 IdKey { get; set; }
        public SolidColorBrush BackgroundColor { get; set; }
    
    
        public CellObject(int row, int column, bool value)
        {
            this.Value = value;
            this.Row = row;
            this.Column = column;
    
            this.Checked += OnChecked;
            this.Unchecked += OnUnchecked;
    
            if (this.Value)
            {
                this.Background = new SolidColorBrush(Colors.Red);
                this.Foreground = new SolidColorBrush(Colors.Green);
    
            }
        }
    
        private void OnUnchecked(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("You unchecked Row: " + this.Row.ToString() + " Column: " + this.Column.ToString());
        }
    
        private void OnChecked(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("You checked Row: " + this.Row.ToString() + " Column: " + this.Column.ToString());
        }
    }
    
    public class KeyGroup
    {
        public String Name { get; set; }
    
        public KeyGroup(String name)
        {
            this.Name = name;
        }
    }
    
    public class ColumnHeaderRow : StackPanel
    {
        public ColumnHeaderRow(List<KeyGroup> keygroups)
        {
            this.Orientation = Orientation.Horizontal;
    
            foreach (KeyGroup kg in keygroups)
            {
                TextBox tb = new TextBox();
                tb.Text = kg.Name;
                this.Children.Add(tb);
            }
        }
    }
    
    推荐文章