如何在xaml中设置自动生成元素的样式

时间:2015-07-13 20:10:07

标签: c# wpf xaml

我正在使用此扩展程序this工具包,它会自动在每个DataGrid列的顶部添加TextBox,以便从以下代码进行过滤。

<DataGrid ColumnHeaderStyle="{StaticResource {ComponentResourceKey 
       TypeInTargetAssembly={x:Type filter:DataGridHeaderFilterControl}, 
       ResourceId=DataGridHeaderFilterControlStyle}}" >

但是,添加的列标题和文本框具有与我想要的不同的样式。

所以我可以这样做来设置列标题的样式,但它不会更改文本框。

<Style x:Key="FilterHeader"
        BasedOn="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type filter:DataGridHeaderFilterControl},
                                                        ResourceId=DataGridHeaderFilterControlStyle}}"
        TargetType="{x:Type DataGridColumnHeader}">

    <Setter Property="Foreground" Value="Blue" />

</Style>

...

<DataGrid ColumnHeaderStyle="{DynamicResource FilterHeader}">

我尝试将其放在Window.Resources中以查看它是否对文本框产生影响。它改变了我的其他文本框,它对扩展名创建的文本框没有任何影响。

<Style TargetType="TextBox">
    <Setter Property="Foreground" Value="Blue" />
</Style>

但没有骰子。我发现的唯一有用的是:

    public void DataGrid_OnLoad(object sender, RoutedEventArgs e)
    {
        IEnumerable<System.Windows.Controls.TextBox> collection =
            FindVisualChildren<System.Windows.Controls.TextBox>(TitleBar);

        foreach (System.Windows.Controls.TextBox tb in collection)
        {
            tb.Foreground = Brushes.Blue;
        }
    }

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

但这似乎是一种垃圾方式。我怎样才能在xaml中完全实现这一点,或者至少在C#中更干净地实现这一目标?

1 个答案:

答案 0 :(得分:1)

从浏览源代码开始,我注意到TextBox实际上不是文本框,而是Textbox的子类。 DelayTextBox

所以你可以修改你的风格来代替它。

<Style TargetType="DelayTextBox">
    <Setter Property="Foreground" Value="Blue" />
</Style>

我没有尝试过,但它应该有用。

<强>更新

终于找到了问题。样式应该在父母的风格中定义。

<Style TargetType="{x:Type filter:DataGridColumnFilter}">
    <Style.Resources>

        <Style TargetType="{x:Type support:DelayTextBox}">
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>

        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
    </Style.Resources>
</Style>

我添加了comboxbox,因为我认为你也想要它。您可以根据需要取出设置器以加粗...正在使用它进行测试。