2010-11-22 53 views
2

我有几列是数字并希望它们右对齐。这是一个有点做作的例子来展示我的问题:将默认资源样式应用于所有DataGridTextColumns

<Window x:Class="MyApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework" xmlns:Windows="clr-namespace:System.Windows;assembly=PresentationFramework" xmlns:Data="clr-namespace:System.Windows.Data;assembly=PresentationFramework" Title="MyApp" 
     Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" Loaded="Window_Loaded"> 
    <Controls:DataGrid Name="MyDataGrid" IsReadOnly="True" 
      xmlns="http://schemas.microsoft.com/wpf/2008/toolkit" ItemsSource="{Data:Binding}" AutoGenerateColumns="True"> 
    <Controls:DataGrid.Columns> 
     <!-- This is a product name and is left justified by default --> 
     <Controls:DataGridTextColumn Header="ProductName" Binding="{Data:Binding Path=ProductName}" /> 
     <!-- The rest of the columns are numeric and I would like for them to be right justified --> 
     <Controls:DataGridTextColumn Header="ProductId1" Binding="{Data:Binding Path=ProductId1}" > 
     <Controls:DataGridTextColumn.ElementStyle> 
      <Windows:Style TargetType="Controls:TextBlock"> 
      <Windows:Setter Property="HorizontalAlignment" Value="Right"/> 
      </Windows:Style> 
     </Controls:DataGridTextColumn.ElementStyle> 
     </Controls:DataGridTextColumn> 
     <Controls:DataGridTextColumn Header="ProductId2" Binding="{Data:Binding Path=ProductId2}" > 
     <Controls:DataGridTextColumn.ElementStyle> 
      <Windows:Style TargetType="Controls:TextBlock"> 
      <Windows:Setter Property="HorizontalAlignment" Value="Right"/> 
      </Windows:Style> 
     </Controls:DataGridTextColumn.ElementStyle> 
     </Controls:DataGridTextColumn> 
     <Controls:DataGridTextColumn Header="ProductId3" Binding="{Data:Binding Path=ProductId3}" > 
     <Controls:DataGridTextColumn.ElementStyle> 
      <Windows:Style TargetType="Controls:TextBlock"> 
      <Windows:Setter Property="HorizontalAlignment" Value="Right"/> 
      </Windows:Style> 
     </Controls:DataGridTextColumn.ElementStyle> 
     </Controls:DataGridTextColumn> 
     <!-- More numeric columns follow... --> 
    </Controls:DataGrid.Columns> 
    </Controls:DataGrid> 
</Window> 

右对齐样式重复所有,但第一列和似乎是多余的。如果只有我可以在这个网格中设置DataGridTextColumns是正确的,那么我只需要明确地左对齐第一列。我怎么能做到这一点,也许使用风格作为资源?有没有更好的办法?

回答

7

DataGridTextColumn不会从FrameworkElement派生,因此您无法为其创建样式。

最简单的方法就是为DataGridCell创建一个样式,并从那里对齐TextBlock。然后设置CellStyle = {x:空}(或者你可能需要的任何其他方式)针对列不应该有这样的

<Controls:DataGrid ...> 
    <Controls:DataGrid.Resources> 
     <Windows.Style TargetType="Controls:DataGridCell"> 
      <Windows.Setter Property="TextBlock.HorizontalAlignment" Value="Right"/> 
     </Windows.Style> 
    </Controls:DataGrid.Resources> 
    <Controls:DataGrid.Columns> 
     <!-- This is a product name and is left justified by default --> 
     <Controls:DataGridTextColumn Header="ProductName" 
            Binding="{Binding Path=ProductName}" 
            CellStyle="{x:Null}"/> 

更新

但是,如果你想申请一个样式到DataGridTextColumn这样的东西是必需的。

首先,我们需要一个可以“保持风格”的助手类。在它中,我们添加了所有我们希望能够使用Style的属性(这不在FrameworkElement中)。在这种情况下ElementStyle。

public class DataGridTextColumnStyleHelper : FrameworkElement 
{ 
    public DataGridTextColumnStyleHelper(){} 
    public static readonly DependencyProperty ElementStyleProperty = 
     DependencyProperty.Register(
      "ElementStyle", 
      typeof(Style), 
      typeof(DataGridTextColumnStyleHelper)); 
    public Style ElementStyle 
    { 
     get { return (Style)GetValue(ElementStyleProperty); } 
     set { SetValue(ElementStyleProperty, value); } 
    } 
} 

然后我们添加在XAML

<Style x:Key="DataGridTextColumnStyle" 
     TargetType="local:DataGridTextColumnStyleHelper"> 
    <Setter Property="ElementStyle"> 
     <Setter.Value> 
      <Style TargetType="TextBlock"> 
       <Setter Property="HorizontalAlignment" Value="Right"/> 
      </Style> 
     </Setter.Value> 
    </Setter> 
</Style> 

的作风和能够在我们需要另一个助手类与TextColumnStyle属性DataGridTextColumn应用此样式。其中,我们使用反射和SetValue来应用样式。

public class MyDataGridHelper : DependencyObject 
{ 
    private static readonly DependencyProperty TextColumnStyleProperty = DependencyProperty.RegisterAttached(
     "TextColumnStyle", 
     typeof(Style), 
     typeof(MyDataGridHelper), 
     new PropertyMetadata(MyPropertyChangedCallback)); 
    public static void SetTextColumnStyle(DependencyObject element, string value) 
    { 
     element.SetValue(TextColumnStyleProperty, value); 
    } 
    public static Style GetTextColumnStyle(DependencyObject element) 
    { 
     return (Style)element.GetValue(TextColumnStyleProperty); 
    } 
    private static void MyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if (DesignerProperties.GetIsInDesignMode(d) == true) 
     { 
      return; 
     } 
     DataGridTextColumn textColumn = (DataGridTextColumn)d; 
     Style textColumnStyle = e.NewValue as Style; 
     foreach (SetterBase setterBase in textColumnStyle.Setters) 
     { 
      if (setterBase is Setter) 
      { 
       Setter setter = setterBase as Setter; 
       if (setter.Value is BindingBase) 
       { 
        //Not done yet.. 
       } 
       else 
       { 
        Type type = textColumn.GetType(); 
        PropertyInfo propertyInfo = type.GetProperty(setter.Property.Name); 
        propertyInfo.SetValue(textColumn, setter.Value, null); 
       } 
      } 
     } 
    } 
} 

最后,我们可以使用样式上DataGridTextColumn这样

<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=ProductId1}" 
    local:MyDataGridHelper.TextColumnStyle="{StaticResource DataGridTextColumnStyle}">