【问题标题】:binding datatable columns to class property stored in a list将数据表列绑定到存储在列表中的类属性
【发布时间】:2014-10-09 17:03:15
【问题描述】:

对不起,令人困惑的标题。我有一个绑定到数据表的动态生成的网格。单击列时,我创建一个新类来存储过滤所需的信息(不同的项目列表、列索引、标题颜色等。我将这些存储在一个列表中。我有一个模板标题列,它创建一个标签和按钮在标题顶部的堆栈面板中。我使用代码隐藏来获取列索引并在视图模型中设置属性。

一切都很好,除了我不太确定如何将标签的背景颜色绑定到 columnIndex 属性 = 实际列索引的列表。我知道这可能仍然相当混乱,这里是代码:

Xaml 模板列:

<local:UserControlViewBase.Resources>
    <Style TargetType="DataGridColumnHeader">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border BorderBrush="Black" BorderThickness="1">
                        <StackPanel Orientation="Horizontal" Width="150">
                            <Label Width="90" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridColumnHeader}},Path=Column.Header}"
                                Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            <Button Content="Ok" Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</local:UserControlViewBase.Resources>

代码隐藏(Xaml.cs 文件):

private void TestListView_MouseUp(object sender, RoutedEventArgs e)
    {
        GenericQueueViewModel temp = (GenericQueueViewModel)this.DataContext;
        DataGridColumnHeader oTest;
        Button oBtn;
        int x = 0;
        if (!(e.OriginalSource.GetType() == typeof(Button)))
        {
            return;               
        }
        else
        {
            oBtn = (Button)e.OriginalSource;
            DataGrid oTst = (DataGrid)e.Source;
            DataGridColumn oCol = (DataGridColumn)oTst.Columns.FirstOrDefault(y => y.Header == oBtn.DataContext);
            int index = oTst.Columns.IndexOf(oCol);

            DataGridColumnHeader colHeader = GetHeader(oCol, oTst);


            double newX = temp.OldScrollValue;               
            for (int i = 0; i < index; i++)
            {
                newX += oTst.Columns[i].ActualWidth;
            }

            Thickness oThick = new Thickness(newX, -122, 0, 0);
            temp.FilterWindowMargin = oThick;
            x = (sender as DataGrid).Columns.IndexOf(oCol);
            colHeader.Background = System.Windows.Media.Brushes.LightSkyBlue;
        }

        temp.UpdateFilterList(x);
    }

ViewModel 类:

[SerializableAttribute]
    public class FilterList
    {
        private int _columnIndex;

        public int ColumnIndex
        {
            get { return _columnIndex; }
            set 
            { 
                _columnIndex = value;
            }
        }

        private System.Windows.Media.Brush _headerColor;

        public System.Windows.Media.Brush HeaderColor
        {
            get { return _headerColor; }
            set 
            { 
                _headerColor = value; 
            }
        }


        private Nullable<bool> _selectAll;

        public Nullable<bool> SelectAll
        {
            get { return _selectAll; }
            set 
            { 
                _selectAll = value; 
            }
        }


        private List<CheckedListItem<DistinctColumnData>> _filterItems;

        public List<CheckedListItem<DistinctColumnData>> FilterItems
        {
            get { return _filterItems; }
            set 
            {
                LastFilterItems = _filterItems;
                _filterItems = value;
            }
        }

        private List<CheckedListItem<DistinctColumnData>> _viewableFilterItems;

        public List<CheckedListItem<DistinctColumnData>> ViewableFilterItems
        {
            get { return _viewableFilterItems; }
            set 
            { 
                _viewableFilterItems = value; 
            }
        }


        private List<CheckedListItem<DistinctColumnData>> _lastFilterItems;

        public List<CheckedListItem<DistinctColumnData>> LastFilterItems
        {
            get { return _lastFilterItems; }
            set { _lastFilterItems = value; }
        }

        private bool _isFiltered;

        public bool IsFiltered
        {
            get { return _isFiltered; }
            set 
            { 
                _isFiltered = value; 
            }
        }


        private bool _isFilterable;

        public bool IsFilterable
        {
            get { return _isFilterable; }

            set 
            { 
                _isFilterable = value; 
            }
        }


        public FilterList()
            : this(-1) { }

        public FilterList(int columnIndex)
            : this(columnIndex, new List<CheckedListItem<DistinctColumnData>>()) { }

        public FilterList(List<CheckedListItem<DistinctColumnData>> filterList)
            : this(-1, filterList) { }

        public FilterList(int columnIndex, List<CheckedListItem<DistinctColumnData>> filterList)
            : this(columnIndex, filterList, false) { }

        public FilterList(int columnIndex, List<CheckedListItem<DistinctColumnData>> filterList, bool isFilterable)
        {
            FilterItems = filterList;
            ColumnIndex = columnIndex;
            IsFilterable = isFilterable;
            HeaderColor = System.Windows.Media.Brushes.Transparent;
        }
    }

ViewModel 列表:

private List<FilterList> _filterColumns;

    public List<FilterList> FilterColumns
    {
        get { return _filterColumns; }
        set 
        { 
            _filterColumns = value;
            OnPropertyChanged(() => FilterColumns);
        }
    }

所以基本上,我需要以某种方式将 xaml DataGridColumnHeader 模板标签背景绑定到 List 中的 FilterList,其中单击了 FilterList.columnIndex = DataGrid 列。代码隐藏 (xaml.cs) 中的代码行:

DataGridColumnHeader colHeader = GetHeader(oCol, oTst);

确实获得了一个标头对象(GetHeader 是我在此处的另一篇文章中找到的一种方法)。但它似乎并没有真正做任何事情。如果我从column0获取标题,并将其颜色设置为LightBlue,然后再次单击column0,header.background = null ...即使当我单步执行它时它确实会更改为十六进制值..下一次它再次抓住标题,background = null ...

这是一个通用表,需要能够绑定到发送的任何表,具有任意数量的列/行,并提供过滤功能。过滤器功能已经在工作,我只是不知道如何更改标题的背景颜色(技术上,标题顶部的标签),以便他们可以直观地看到过滤了哪些列。

【问题讨论】:

  • 所以我发现了如何让标签背景发生变化,我将主堆栈面板背景设置为这样。当我过滤 column0 时,它适用于 0 索引。但是,它正在更改所有列(正如预期的那样......它是一个模板)。我需要知道如何让它动态地将列索引附加到列。这也不是检查 List 中的 columnIndex 属性。 Background="{Binding DataContext.FilterColumns[0].HeaderColor,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:UserControlViewBase}},Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
  • 轻微修正。看起来标题颜色正在发生变化,但它在 Stackpanel 下不可见,即使背景 =“透明”......不知道为什么。当我单击按钮时,标题变为蓝色,按钮消失。当我关闭过滤器窗口时,按钮又回来了,颜色丢失了。我删除了标签,并给按钮一个 margin= 125,0,0,0 以便它强制列宽,但仍然看不到标题颜色...

标签: c# wpf xaml


【解决方案1】:

我想我明白了。必须使用转换器。修改代码如下,添加转换器:

<local:UserControlViewBase.Resources>
    <Converters:BGConverter x:Key="BackgroundConverter"/>
    <Style TargetType="DataGridColumnHeader">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border BorderBrush="Black" BorderThickness="1" Width="150">
                        <StackPanel x:Name="testtest" Orientation="Horizontal"
                            Background="{Binding Converter={StaticResource BackgroundConverter}, ConverterParameter={x:Reference TestListView}}">                                        
                            <Label Width="90" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridColumnHeader}},Path=Column.Header}"
                                Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            <Button Content="Ok" Padding="12,0,12,0"  HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10,0,0,0"/>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>        
</local:UserControlViewBase.Resources>

现在,我可以通过转换器添加逻辑。这使用单例,所以如果你不是粉丝,你需要找到另一种方法来获取你的虚拟机。它在前几次将 VM 传递给转换器,所以我将它存储在我的 mainviewmodel 中,然后在它开始在列中传递时使用它:

 public class BGConverter : IValueConverter
{
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        GenericQueueViewModel oQueue;
        System.Windows.Media.Brush returnBrush;

        DataGrid oGrid = (DataGrid)parameter;
        if (value == null)
        {
            returnBrush = System.Windows.Media.Brushes.Transparent;
        }
        else if (oGrid == null)
        {
            returnBrush = System.Windows.Media.Brushes.Transparent;
        }
        else if (value.GetType() == typeof(GenericQueueViewModel))
        {
            MainViewModel.Instance.GenericVM = (GenericQueueViewModel)value;
            returnBrush = System.Windows.Media.Brushes.Transparent;
        }

        else
        {
            oQueue = MainViewModel.Instance.GenericVM;
            DataGridColumn oCol = oGrid.Columns.FirstOrDefault(y => y.Header == value);
            int colIndex = oGrid.Columns.IndexOf(oCol);
            string colName = (string)value;

            var fList = oQueue.FilterColumns.FirstOrDefault(y => y.ColumnIndex == colIndex && y.IsFiltered == true);
            if (fList == null)
            {
                returnBrush = System.Windows.Media.Brushes.Transparent;
            }
            else
            {
                returnBrush = System.Windows.Media.Brushes.Red;
            }
        }

        return returnBrush;
    }
}

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 2012-10-08
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多