wpf - 如何将样式应用于自定义控件库中的 DependencyObject

标签 wpf

我正在创建一个基于 TreeView 的可重用自定义控件。我在自定义控件上为控件中的列创建了一个依赖属性,如下所示:

    public GridViewColumnCollection Columns
    {
        get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }
        set { SetValue(ColumnsProperty, value); }
    }

    public static readonly DependencyProperty ColumnsProperty =
        DependencyProperty.Register("Columns", typeof(GridViewColumnCollection), typeof(TreeListView), new PropertyMetadata(new GridViewColumnCollection()));

这让我可以在 XAML 中指定一堆列。问题是我需要第一列有一个自定义单元格模板。我打算通过从 GridViewColumn 派生一个类来解决这个问题,如下所示:
public class TreeGridViewColumn : GridViewColumn
{
}

然后在 Generic.xaml 中为自定义控件提供所需的样式:
<Style TargetType="{x:Type local:TreeGridViewColumn}">
    <Setter Property="CellTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border Background="Black" /> <!-- Just for example -->
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

但是,该样式永远不会应用于 TreeGridViewColumn 的实例。我知道我可能需要添加:
DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridViewColumn), new FrameworkPropertyMetadata(typeof(TreeGridViewColumn)));

但是我不能这样做,因为 GridColumn 基类不是 FrameworkObject,它是一个 DependencyObject。如何将样式应用于自定义控件库中定义的 GridViewColumn 的后代?

最佳答案

这样想: TreeGridViewColumn 应该是一个虚拟对象,其中包含列本身的重要信息,例如宽度和高度,以及该列标题下的每个单元格,例如单元格模板本身。因此,不要尝试从 TreeGridViewColumn 中创建 FrameworkElement。下面是一个如何最终使用 TreeGridViewColumn 的示例。

        <TreeGridViewColumn Header="First Col" Width="50">
            <TreeGridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button>
                        click me
                    </Button>
                </DataTemplate>
            </TreeGridViewColumn.CellTemplate>
        </TreeGridViewColumn>

一旦您准备好显示列和单元格,我建议您编写自己的自定义面板,该面板通过调用它们的 Measure 和Arrange 方法来处理 FrameworkElements,允许您以您想要的方式定位列和单元格。您最终将在自定义面板类中进行大量数学运算。此外,这意味着您最终将花费一个月的时间对 TreeGridView 进行编程。建议你走捷径,下载这种东西的代码。网上已经很少有 TreeListViews 了。拿他们的 dll 看看它是否适合你

编辑:

好的,这是一个如何解决问题的建议。这只是一个建议

DefaultTextColumnData 类是一个虚拟对象,包含所有必要的信息,如列宽等。

DataGridCellControl 将是绘制单元格的 FrameworkElement。它是一个 FrameworkElement,因此它将在您的 generic.xaml 资源字典中具有定义的样式。

总结一下 DefaultTextColumnData 将保存列本身的所有信息。 DataGridCellControl 将是一个控件,如果该列中有 20 个单元格,它可能最终有 20 个自身实例。

DataGridCellControl 必须知道它的列。
这是 DataGridCellControl 的代码的样子:
class DefaultTextColumnData : DataGridColumn
{
}

class ComplexColumnData : DataGridColumn
{
}

class DataGridCellControl : Control
{
  public DataGridColumn Column
  {
    get; set;
  }

  public DataTemplate DefaultTextCellTemplate
  {
    get; set;
  }

  public override Size MeasureOverride(Size size)
  {
   ...
   if(this.Column is DefaultTextColumnData)
   {
    this.Template = this.DefaultTextCellTemplate
   }

   if(this.Column is ComplexColumnData)
   {
    this.Template = ...
   }
   ...
   return new Size(30, 30);
  }
}

DefaultTextCellTemplate 将在您的 generic.xaml 中设置,如下所示:
<Style TargetType={x:Type DataGridCellControl}>
 <Setter Property="DefaultTextCellTemplate">
  <Setter.Value>
   <DataTemplate>
    <TextBlock Background="Black" Margin="5"/>
     ....

这就是您在资源字典中设置默认单元格模板的方式。

关于wpf - 如何将样式应用于自定义控件库中的 DependencyObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34889913/

相关文章:

wpf - 将 WPF 数据网格绑定(bind)到多个数据源

c# - Path= 在 XAML 中有什么用?

wpf - 在WPF中构建Metro风格的应用程序需要哪些组件?

.net - 如何测试 WPF 用户界面?

c# - 修改 ObservableCollection 的一项

c# - 如何从 View 模型更新 View 中的单选按钮?

wpf - MVVM概念的混淆

wpf - 如何在 Visual Studio 中快速切换 XAML 和设计模式

c# - 更改图钉 WPF 的图像

c# - WPF UserControl.Resources 引用