2012-11-06 185 views
0

我有一个WPF数据网格,我已经绑定了一个observablecollection。它工作正常,但问题是我在运行时在单元级别应用样式。下面提到了一个示例方法ApplyStyleAtCellLevelInDataGrid()。我必须调用这个方法两次才能显示WPF DataGrid中的样式的效果。为什么会这样......WPF Datagrid WPF样式问题

这里是XAML

<Style x:Key="BaseStyle" TargetType="{x:Type TextBlock}"> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="Black"/>   
    <Setter Property="FontSize" Value="10"/> 
    <Setter Property="TextAlignment" Value="Center"/> 
</Style> 

<Style TargetType="{x:Type TextBlock}" x:Key="Col1Style" BasedOn="{StaticResource BaseStyle}"> 

     <Setter Property="Background"> 
      <Setter.Value> 
       <SolidColorBrush Color="Tomato"/> 
      </Setter.Value> 
     </Setter>    

     <Style.Triggers> 
      <EventTrigger RoutedEvent="Binding.TargetUpdated"> 
       <BeginStoryboard HandoffBehavior="Compose"> 
        <Storyboard TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"> 
        <ColorAnimation Duration="0:0:1.5" To="DarkRed" AutoReverse="True" RepeatBehavior="1" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Style.Triggers> 
    </Style> 

<风格X:键= “DGCellStyle” 的TargetType = “{x:类型DataGridCell}”>

 <Setter Property="BorderThickness" Value="0" /> 
     <Setter Property="FontSize" Value="10"></Setter> 
     <Setter Property="Foreground" Value="Black"></Setter>   
    </Style> 

电网宣言在XAML

<DataGrid Name="dataGrid1" ItemsSource="{Binding Values}" CellStyle="{StaticResource DGCellStyle}" SnapsToDevicePixels="True" UseLayoutRounding="False"> 

    <DataGrid.Columns> 
     <DataGridTextColumn Header="Value" Binding="{Binding Value1, Mode=OneWay, NotifyOnTargetUpdated=True}" Width="0.25*"/> 
     <DataGridTextColumn Header="Value 1" Binding="{Binding Value2, Mode=OneWay, NotifyOnTargetUpdated=True}" Width="0.25*"/> 
     <DataGridTextColumn Header="Value 2" Binding="{Binding Value3, Mode=OneWay, NotifyOnTargetUpdated=True}" Width="0.25*"/> 
     <DataGridTextColumn Header="Value 3" Binding="{Binding Value4, Mode=OneWay, NotifyOnTargetUpdated=True}" Width="0.25*"/> 
    </DataGrid.Columns>   
</DataGrid> 

代码

private void ApplyStyleAtCellLevelInDataGrid() 

    { 
     if (Values == null || Values.Count == 0) 
     { 
      Values = new ObservableCollection<MyClass>(); 
      Values.Add(new MyClass { Value1 = "1", Value4 = "2", Value2 = "4", Value3 = "3" }); 
      Values.Add(new MyClass { Value1 = "2", Value4 = "3", Value2 = "5", Value3 = "7" }); 
      Values.Add(new MyClass { Value1 = "3", Value4 = "4", Value2 = "7", Value3 = "2" }); 
      Values.Add(new MyClass { Value1 = "4", Value4 = "4", Value2 = "8", Value3 = "6" }); 
     } 
     else 
     { 
      foreach (var item in Values) 
      { 
       MyClass c = item as MyClass; 
       c.Value1 = _rand.Next(0, 100).ToString();   
       c.Value2 = _rand.Next(0, 100).ToString(); 
       c.Value3 = _rand.Next(0, 100).ToString(); 
       c.Value4 = _rand.Next(0, 100).ToString(); 
      } 
     } 

     ////////////// 

     DataGridCell cell = GetCell(1, 1); 

     Style defaultStyle = (Style)FindResource("NewStyle"); 
     ((TextBlock)cell.Content).Style = defaultStyle; 

     cell = GetCell(1, 2); 
     defaultStyle = (Style)FindResource("NewStyleExtended"); 
     ((TextBlock)cell.Content).Style = defaultStyle; 

     cell = GetCell(2, 2); 
     defaultStyle = (Style)FindResource("NewStyle"); 
     ((TextBlock)cell.Content).Style = defaultStyle; 

     cell = GetCell(2, 3); 
     defaultStyle = (Style)FindResource("Col1Style"); 
     ((TextBlock)cell.Content).Style = defaultStyle; 
    } 


private void Window_Loaded(object sender, RoutedEventArgs e) 
    {   
// Single call of this method does not work, 

I have to call two times then it shows the effect 

     ApplyStyleAtCellLevelInDataGrid(); 
     ApplyStyleAtCellLevelInDataGrid(); 
    } 

回答

0

将您的Style的TargetTypeTextBlock更改为DataGridCell,然后将样式应用为DataGrid.CellStyle。由于您已将CellStyle设置为DGCellStyle,因此您可能必须合并这两种样式。

另外,你需要在你的基本样式改变TextAlignmentHorizontalAlignment因为TextAlignment是不是你可能会感兴趣的实施DataTemplateSelector的DataGridCell

<Style x:Key="BaseStyle" TargetType="{x:Type DataGridCell}"> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="Black"/>   
    <Setter Property="FontSize" Value="10"/> 
    <Setter Property="HorizontalAlignment" Value="Center"/> 
</Style> 

<Style TargetType="{x:Type DataGridCell}" x:Key="Col1Style" BasedOn="{StaticResource BaseStyle}"> 
    <Setter Property="Background"> 
     <Setter.Value> 
      <SolidColorBrush Color="Tomato"/> 
     </Setter.Value> 
    </Setter>    

    <Style.Triggers> 
     <EventTrigger RoutedEvent="Binding.TargetUpdated"> 
      <BeginStoryboard HandoffBehavior="Compose"> 
       <Storyboard TargetProperty="(DataGridCell.Background).(SolidColorBrush.Color)"> 
       <ColorAnimation Duration="0:0:1.5" To="DarkRed" AutoReverse="True" RepeatBehavior="1" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Style.Triggers> 
</Style> 

而且

<DataGrid CellStyle="{StaticResource Col1Style}" ... /> 
+0

感谢您的回答,但我的邮件的问题是,为什么我叫ApplyStyleAtCellLevelInDataGrid() ;在Window_Loaded事件中使用2次来显示样式的效果?调用它一次不会在屏幕上显示任何东西 –

+0

@AsadNaeem我最好的猜测是它与WPF的[DispatcherPriority](http://msdn.microsoft.com/en-us/library/system.windows.threading)有关。 dispatcherpriority.aspx),并且第一次运行是创建'Grid'绑定的'Values'集合,并且DataGrid项目还没有完成渲染,或者在渲染过程和覆盖过程中应用了默认样式你的自定义风格,所以这就是为什么需要第二次运行。不过,如果不设置测试场景,我也不会知道。 – Rachel

0

属性。该对象用于在任何数据项上提供显示逻辑。

这里有一个快速教程:​​

+0

感谢您的答案,但我的邮件问题是,为什么我要调用ApplyStyleAtCellLevelInDataGrid();在Window_Loaded事件中显示风格的效果?调用一次在屏幕上不显示任何内容 –

+0

我不知道。但是在WPF中有一些接口是为了修改基于自定义逻辑的样式而不使用它们。我的回答是:如果您在处置时使用了工具而不是绕过它,那么您甚至不需要使用“ApplystyleAtCellLevel”函数。 – Joe

0

在App.xaml中的应用程序标记添加

"xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"

<Application.Resources>标签中添加代码

<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type dg:DataGridColumnHeader}"> 
    <Setter Property="HorizontalAlignment" Value="Center" /> 
</Style> 

<Style x:Key="CellRightAlign" TargetType="{x:Type dg:DataGridCell}"> 
    <Setter Property="HorizontalAlignment" Value="Right" /> 
</Style> 

现在落后的AutoGeneratedColumns事件添加到您的DataGrid

Style RightAlign = (Style)FindResource("CellRightAlign"); 
yourGrid.Columns[0].CellStyle = RightAlign;