我有一个 DataGrid,我试图根据该网格单元中显示的文本来设置每个元素的背景。网格单元定义如下,并且访问它们可以正常工作:
<Window.Resources>
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="MouseDown" Handler="Clicked" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
不起作用的部分是我无法设置 DataGridTextColumn 的样式,下面的 setter 都没有执行任何操作。 DataGrid 本身显示正确。
<DataGrid Name="dataGrid1" AutoGenerateColumns="False" IsReadOnly="true">
<DataGridTextColumn>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Background" Value="Black"/>
<Style.Triggers>
<Trigger Property="Text" Value="None">
<Setter Property="Background" Value="Aquamarine"/>
</Trigger>
<Trigger Property="Text" Value="First">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid>
预先感谢您的帮助。
编辑 1 更新了 NETscape 问题的答案。 1)我的DataGrid显示正确,我什至单击网格中的项目并修改其后面的数据。但是,我的 XAML 中没有设置 DataSource,在我看来只是一个指向 DataGrid 的简单 DataContext。
2)我不认为问题出在我的变量名上,因为下面没有触发器的 setter 属性也没有显示:
<Setter Property="HorizontalAlignment" Value="Center" />
编辑2 再次回应 NETscape 的问题/评论。我最初没有发布我的隐藏代码,因为由于我的所有对象都正确显示,所以我并没有在那里寻找问题。但我想我错了。我的网格和网格中的列的数据绑定(bind)是不同的。我的网格的 DataContext 是一个 RowObject 数组。每个 DataGridTextColumn 的数据上下文是我的 RowObject 中与一周中的特定一天相关的一个条目。
DataGridTextColumn cSunday = new DataGridTextColumn();
DataGridTextColumn cMonday = new DataGridTextColumn();
public TimeSlice[] TimeArray = new TimeSlice[48];
MyWnd.dataGrid1.DataContext = TimeArray; //sets DataContext for the DataGrid
CultureInfo cu = new CultureInfo(App.CultureID);
//creates one column
cSunday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Sunday);
cSunday.Binding = new Binding("StatusSunday");
Wnd.dataGrid1.Columns.Add(cSunday);
cMonday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Monday);
cMonday.Binding = new Binding("StatusMonday");
Wnd.dataGrid1.Columns.Add(cMonday);
编辑3 为了完整起见,添加从 NETscape 的答案派生的工作解决方案。 XAML:
<Window
<Window.Resources>
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="MouseDown" Handler="Clicked" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MyDataGridTextColumnElementStyle"
TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Background" Value="Black"/>
<Style.Triggers>
<Trigger Property="Text" Value="None">
<Setter Property="Background" Value="Aquamarine"/>
</Trigger>
<Trigger Property="Text" Value="First">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Name="MainView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row ="0">
</Border>
<Border Grid.Row="1">
<DataGrid Name="dataGrid1" AutoGenerateColumns="False" IsReadOnly="true"/>
</Border>
</Grid>
</Window>
我的 View 模型中用于设置前 2 天/列的代码:
public TimeSlice[] TimeArray = new TimeSlice[48];
public ViewModelr(WndCalendar Wnd)
{
MyWnd = Wnd;
MyWnd.DataContext = this;
MyWnd.dataGrid1.DataContext = TimeArray;
cTime.Header = "";
cTime.Binding = new Binding("TimeofDay");
Wnd.dataGrid1.Columns.Add(cTime);
CultureInfo cu = new CultureInfo(App.CultureID);
cSunday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Sunday);
cSunday.Binding = new Binding("StatusSunday");
Wnd.dataGrid1.Columns.Add(cSunday);
cSunday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;
cMonday.Header = cu.DateTimeFormat.GetDayName(DayOfWeek.Monday);
cMonday.Binding = new Binding("StatusMonday");
Wnd.dataGrid1.Columns.Add(cMonday);
cMonday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;
最佳答案
Frank E,您的编辑 2 可能已经泄露了您的问题;了解何时以编程方式执行操作总是很有帮助的!
在 Windows.Resources
中设置 Style
的意思是:“嘿,对于此控件中的任何 DataGridCell
,应用此样式”。这就是为什么它可以正常工作,因为添加所有信息后,样式仍然会应用;这就是为什么它似乎有效。
现在请注意,您正在定义一个DataGridTextColumn
,它是ElementStyle
。这并没有应用于所有 DataGridTextColumn
,这可能是您所想的。相反,它被应用于单个 DataGridTextColumn
!因为您没有为该 DataGridTextColumn
定义任何内容,所以它实际上是在 DataGrid
中绘制的,但由于该列没有内容,因此它的 Width = 0
。
由于您是以编程方式创建其他列,因此您需要以编程方式应用样式。所以你应该有这样的东西:
<Window.Resources>
<Style TargetType="{x:Type DataGridCell}">
<EventSetter Event="MouseDown" Handler="Clicked" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MyDataGridTextColumnElementStyle"
TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Background" Value="Black"/>
<Style.Triggers>
<Trigger Property="Text" Value="None">
<Setter Property="Background" Value="Aquamarine"/>
</Trigger>
<Trigger Property="Text" Value="First">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
然后,当您在代码隐藏中创建列时,请执行以下操作:
cSunday.ElementStyle = MyWnd.FindResource("MyDataGridTextColumnElementStyle") as Style;
对于您正在创建的每一列。
据我了解,不分配 x:Key
会将样式应用于 TargetType
类型的所有元素,因此,由于我们分配了 x :Key
为第二种样式,并非所有 TextBlock
都会分配该样式,只有我们指定的样式。
请告诉我这是否有帮助。
关于c# - 设置 DataGrid 列的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23998136/