为什么不能创建一个DataGridTextColumn? [英] Why can't I style a DataGridTextColumn?

查看:112
本文介绍了为什么不能创建一个DataGridTextColumn?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用以下代码创建一个 DataGridTextColumn 的样式

 < Style TargetType ={x:Type DataGridTextColumn}> 
...
< / Style>

然而,Visual Studio 2010突出显示 {x:Type DataGridTextColumn} 一个蓝线,并阐述:异常被调用的目标抛出。



为什么会发生这种情况,我该如何解决?

解决方案

您不能对 DataGridTextColumn 因为 DataGridTextColumn 不派生自 FrameworkElement (或 FrameworkContentElement )。只有FrameworkElement等支持样式。



当您尝试在XAML中为不是 FrameworkElement FrameworkContentElement 您会收到该错误消息。



您如何解决这个问题?和任何问题一样,有意愿的是有办法。在这种情况下,我认为最简单的解决方案是为DataGrid创建一个附加属性来分配DataGridColumn样式:

 < DataGrid。 ..> 
< local:MyDataGridHelper.TextColumnStyle>
< Style TargetType =FrameworkElement>
... setters here ...
< / Style>
< / local:MyDataGridHelper.TextColumnStyle>
...

这些实现将是以下几点:

  public class MyDataGridHelper:DependencyObject 
{
//使用propa剪切创建带元数据的附加TextColumnStyle:
。 .. RegisterAttached(TextColumnStyle,typeof(Style),typeof(MyDataGridHelper),new PropertyMetadata
{
PropertyChangedCallback =(obj,e)=>
{
var grid =(DataGrid)obj;
if(e.OldValue == null&& e.NewValue!= null)
grid.Columns.CollectionChanged + =(obj2,e2)=>
{
UpdateColumnStyles(grid);
}
}
}
private void UpdateStyles(DataGrid grid)
{
var style = GetTextColumnStyle(grid);
foreach(在grid.Columns.OfType< DataGridTextColumn>())中的var列
foreach(style.Setters.OfType&Set; Setter>())中的var setter
if (setter.Value是BindingBase)
BindingOperations.SetBinding(column,setter.Property,setter.Value);
else
column.SetValue(setter.Property,setter.Value);
}
}

它的工作原理是,随时附加属性已更改,为网格上的Columns.CollectionChanged事件添加了处理程序。当CollectionChanged事件触发时,所有列都将更新为设置的样式。



请注意,上述代码不处理删除样式的情况,优雅地添加:两个事件处理程序被注册。对于一个非常强大的解决方案,您可以通过添加包含事件处理程序的其他附加属性来解决此问题,以便事件处理程序可以被注销,但为了您的目的,我认为这不重要。



另一个需要注意的是,直接使用SetBinding和SetValue会导致DependencyProperty的BaseValueSource为 Local 而不是 DefaultStyle 。这可能在你的情况下没有什么不同,但我以为我应该提到它。


I tried to create a Style for DataGridTextColumn with the following code

<Style TargetType="{x:Type DataGridTextColumn}">
           ...
</Style>

However, Visual Studio 2010 highlights {x:Type DataGridTextColumn} with a blue line and elaborates: Exception has been thrown by the target of an invocation.

Why does this happen and how do I fix it?

解决方案

You can't style the DataGridTextColumn because DataGridTextColumn does not derive from FrameworkElement (or FrameworkContentElement). Only FrameworkElement, etc supports styling.

When you attempt to create a style in XAML for any type that is not a FrameworkElement or FrameworkContentElement you get that error message.

How do you solve this? As with any problem, where there is a will there is a way. In this case I think the easiest solution is to create an attached property for DataGrid to assign a DataGridColumn style:

<DataGrid ...>
  <local:MyDataGridHelper.TextColumnStyle>
    <Style TargetType="FrameworkElement">
      ... setters here ...
    </Style>
  </local:MyDataGridHelper.TextColumnStyle>
  ...

The implementation would be something along these lines:

public class MyDataGridHelper : DependencyObject
{
  // Use propa snipped to create attached TextColumnStyle with metadata:
  ... RegisterAttached("TextColumnStyle", typeof(Style), typeof(MyDataGridHelper), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
    {
      var grid = (DataGrid)obj;
      if(e.OldValue==null && e.NewValue!=null)
        grid.Columns.CollectionChanged += (obj2, e2) =>
        {
          UpdateColumnStyles(grid);
        }
    }
  }
  private void UpdateStyles(DataGrid grid)
  {
    var style = GetTextColumnStyle(grid);
    foreach(var column in grid.Columns.OfType<DataGridTextColumn>())
      foreach(var setter in style.Setters.OfType<Setter>())
        if(setter.Value is BindingBase)
          BindingOperations.SetBinding(column, setter.Property, setter.Value);
        else
          column.SetValue(setter.Property, setter.Value);
  }
}

The way this works is, any time the attached property is changed, a handler is added for the Columns.CollectionChanged event on the grid. When the CollectionChanged event fires, all columns are updated with the style that was set.

Note that the above code does not handle the situation where a style is removed and re-added gracefully: Two event handlers are registered. For a really robust solution you would want to fix this by adding another attached property containing the event handler so the event handler could be unregistered, but for your purpose I think this is unimportant.

Another caveat here is that the direct use of SetBinding and SetValue will cause the DependencyProperty to have a BaseValueSource of Local instead of DefaultStyle. This will probably make no difference in your case but I thought I should mention it.

这篇关于为什么不能创建一个DataGridTextColumn?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆