很抱歉这个令人困惑的标题。我有一个动态生成的网格绑定到数据表。单击一列时,我创建了一个新类,用于存储过滤所需的信息(不同的项目列表,列索引,标题颜色等。我将它们存储在List中。我有一个模板标题列,用于创建标签和按钮在标题顶部的堆栈面板中。我使用代码隐藏来获取列索引并在视图模型中设置属性。
一切都很好用,除了我不太确定如何将标签的背景颜色绑定到listIndex属性=实际列索引的List。我知道这可能仍然相当令人困惑,这里是代码:
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>
Code Behind(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 ......
这是一个通用表,需要能够绑定到任何发送的表,包含任意数量的列/行,并提供过滤功能。过滤器功能已经工作,我只是无法弄清楚如何更改标题的背景颜色(技术上,标题顶部的标签),以便他们可以直观地看到哪些列被过滤。
答案 0 :(得分:0)
我想我明白了。必须使用转换器。改变代码如下,添加转换器:
<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>
现在,从转换器,我可以添加逻辑。这使用Singleton,所以如果你不是粉丝,你需要找到另一种方法来获取你的VM。它在前几次将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;
}
}