更改 WPF DataGrid 列标题样式、代码隐藏中的菜单可见性?

发布于 2024-10-22 01:47:41 字数 7923 浏览 3 评论 0原文

我有以下“样式”(在 xaml 中定义为资源)。这基本上是一个带有实现行过滤的菜单的“DataGridColumnHeaderStyle”。它使用以下方式分配给 DataGrid: ColumnHeaderStyle="{StaticResource lclDataGridColumnHeaders}"

在代码隐藏中有时我需要禁用在此样式中定义的(行过滤)菜单 (menuColumnOptions)。谁能告诉我如何访问此元素,以便我可以通过 C# 更改其可见性?

我尝试过: myDataGrid.Template.FindName("menuColumnOptions") 但我收到一个错误,必须“应用”有关它的某些内容...

(我想替代解决方案是创建一个重复的“样式”而不使用此菜单并更改所有使用该样式的列...)

<Style x:Key="lclDataGridColumnHeaders" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="{StaticResource appTextColor}"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <Border x:Name="BackgroundBorder"
                        BorderThickness="0,1,0,1" 
                        Background="{StaticResource lclDataGridHeaderBackground}" 
                        BorderBrush="Transparent" 
                        Grid.ColumnSpan="2" />

                <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center" />

                <Path Grid.Column="1" x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" 
                        Width="8" Height="6" Fill="Gray" Stretch="Fill" Margin="0,0,8,0"
                        VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" />


                <Menu Grid.Column="3" x:Name="menuColumnOptions" VerticalAlignment="Center" Background="#FFF9F9F7" HorizontalAlignment="Right" >
                    <MenuItem Padding="0" SubmenuOpened="MenuItemColumnOptions_SubmenuOpened">
                        <MenuItem.Header>
                            <Border BorderBrush="{StaticResource appTextColor}" BorderThickness="1" CornerRadius="2" Height="20" Width="20" >
                                <Path Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Fill="{StaticResource appTextColor}"
                                        Width="10" Height="8" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" Margin="2,0"/>
                            </Border>
                        </MenuItem.Header>
                        <MenuItem x:Name="clearFilterMenuItem" Header="Clear Filter..." Click="ClearFilter_Click" IsEnabled="False">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/edit_undohs.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Equals..." Click="CustomAutoFilter_Click" />
                        <MenuItem Header="Does Not Equal..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Begins With..." Click="CustomAutoFilter_Click"/>
                        <MenuItem Header="Ends With..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Contains..." Click="CustomAutoFilter_Click" />
                        <MenuItem Header="Does Not Contain..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Custom Filter..." Click="CustomAutoFilter_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/Filter2HS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Select Individual Values..." Click="SelectIndividualItems_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/checkboxhs.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Trim Trailing White Spaces..." Click="TrimTrailingWhiteSpaces_Click"/>
                        <MenuItem Header="Capitalization" >
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/FontHS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                            <MenuItem Header="Capitalize Each Word" Click="CapitalizeEachWord_Click"/>
                            <MenuItem Header="UPPERCASE" Click="Uppercase_Click"/>
                            <MenuItem Header="lowercase" Click="Lowercase_Click"/>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Hide Column" Click="HideColumn_Click"/>
                        <Separator />
                        <MenuItem x:Name="deleteColumnMenuItem" Header="Delete Column" Click="dropColumnButton_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/DeleteHS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                    </MenuItem>
                </Menu>

                <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="SortDirection" Value="Ascending">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                    <Setter TargetName="SortArrow" Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="180" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="SortDirection" Value="Descending">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                </Trigger>
                <Trigger Property="SortDirection" Value="{x:Null}">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Collapsed" />
                </Trigger>
                <Trigger Property="DisplayIndex" Value="0">
                    <Setter Property="Visibility" Value="Collapsed" TargetName="PART_LeftHeaderGripper" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True" >
                    <Setter Property="Background" TargetName="BackgroundBorder" Value="{StaticResource appButtonBackgroundHighlight}" />
                    <Setter Property="BorderBrush" TargetName="BackgroundBorder" Value="Transparent" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

I have the following "Style" (defined as a Resource in xaml). This is basically a "DataGridColumnHeaderStyle" with a Menu that implements Row filtering. It is assigned to the DataGrid using: ColumnHeaderStyle="{StaticResource lclDataGridColumnHeaders}"

There are times in Code Behind I need to disable the (row filtering) Menu (menuColumnOptions), which is defined in this Style. Can anyone tell me how to access this element so I can change its Visibility via C#?

I tried: myDataGrid.Template.FindName("menuColumnOptions") but I received an error, something about it must be "applied"...

(I suppose the alternative solution is to create a duplicate "Style" WITHOUT this Menu and change all the Columns to use that style...)

<Style x:Key="lclDataGridColumnHeaders" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="{StaticResource appTextColor}"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <Border x:Name="BackgroundBorder"
                        BorderThickness="0,1,0,1" 
                        Background="{StaticResource lclDataGridHeaderBackground}" 
                        BorderBrush="Transparent" 
                        Grid.ColumnSpan="2" />

                <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center" />

                <Path Grid.Column="1" x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" 
                        Width="8" Height="6" Fill="Gray" Stretch="Fill" Margin="0,0,8,0"
                        VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" />


                <Menu Grid.Column="3" x:Name="menuColumnOptions" VerticalAlignment="Center" Background="#FFF9F9F7" HorizontalAlignment="Right" >
                    <MenuItem Padding="0" SubmenuOpened="MenuItemColumnOptions_SubmenuOpened">
                        <MenuItem.Header>
                            <Border BorderBrush="{StaticResource appTextColor}" BorderThickness="1" CornerRadius="2" Height="20" Width="20" >
                                <Path Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Fill="{StaticResource appTextColor}"
                                        Width="10" Height="8" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" Margin="2,0"/>
                            </Border>
                        </MenuItem.Header>
                        <MenuItem x:Name="clearFilterMenuItem" Header="Clear Filter..." Click="ClearFilter_Click" IsEnabled="False">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/edit_undohs.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Equals..." Click="CustomAutoFilter_Click" />
                        <MenuItem Header="Does Not Equal..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Begins With..." Click="CustomAutoFilter_Click"/>
                        <MenuItem Header="Ends With..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Contains..." Click="CustomAutoFilter_Click" />
                        <MenuItem Header="Does Not Contain..." Click="CustomAutoFilter_Click"/>
                        <Separator />
                        <MenuItem Header="Custom Filter..." Click="CustomAutoFilter_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/Filter2HS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Select Individual Values..." Click="SelectIndividualItems_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/checkboxhs.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Trim Trailing White Spaces..." Click="TrimTrailingWhiteSpaces_Click"/>
                        <MenuItem Header="Capitalization" >
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/FontHS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                            <MenuItem Header="Capitalize Each Word" Click="CapitalizeEachWord_Click"/>
                            <MenuItem Header="UPPERCASE" Click="Uppercase_Click"/>
                            <MenuItem Header="lowercase" Click="Lowercase_Click"/>
                        </MenuItem>
                        <Separator />
                        <MenuItem Header="Hide Column" Click="HideColumn_Click"/>
                        <Separator />
                        <MenuItem x:Name="deleteColumnMenuItem" Header="Delete Column" Click="dropColumnButton_Click">
                            <MenuItem.Icon>
                                <Image Source="/IngramBook.WpfTableEditor;component/Images/DeleteHS.png" Width="16" Height="16"/>
                            </MenuItem.Icon>
                        </MenuItem>
                    </MenuItem>
                </Menu>

                <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
                <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="SortDirection" Value="Ascending">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                    <Setter TargetName="SortArrow" Property="RenderTransform">
                        <Setter.Value>
                            <RotateTransform Angle="180" />
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="SortDirection" Value="Descending">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                </Trigger>
                <Trigger Property="SortDirection" Value="{x:Null}">
                    <Setter TargetName="SortArrow" Property="Visibility" Value="Collapsed" />
                </Trigger>
                <Trigger Property="DisplayIndex" Value="0">
                    <Setter Property="Visibility" Value="Collapsed" TargetName="PART_LeftHeaderGripper" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True" >
                    <Setter Property="Background" TargetName="BackgroundBorder" Value="{StaticResource appButtonBackgroundHighlight}" />
                    <Setter Property="BorderBrush" TargetName="BackgroundBorder" Value="Transparent" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

携余温的黄昏 2024-10-29 01:47:42

您是否能够为 DataGridColumnHeader 类创建一个附加属性(类型布尔值或可见性)并将菜单的 Enabled 或 Visibility 属性绑定到该附加属性?

http://www.deepcode.co.uk /2008/08/exusing-new-properties-for-control_15.html

编辑:

My thought is that an attached property is going to be simpler as you could just set the visibility in XAML, but I tried a quick test and I think the method you are trying to use should work just as well.

Menu myMenu = (Menu)this.myDataGrid.Template.FindName("menuColumnOptions", this.myDataGrid);
menu.Visibility = System.Windows.Visibility.Hidden;

如果您收到错误,您能否在后面的代码中显示您尝试设置可见性的代码?听起来您可能会在完全构建之前尝试访问 DataGridColumnHeader 的模板(在这种情况下,将代码移至 Loaded 事件可能会解决您的问题)。

编辑2:

<Window x:Class="TestApp11.MainWindow" 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:l="clr-namespace:TestApp11"
  xmlns:s="clr-namespace:System;assembly=mscorlib"
  Title="Window1" Height="500" Width="800">
    <Grid>
        <Grid.Resources>
            <Style x:Key="MyButtonStyle" TargetType="Button">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border BorderBrush="Red" BorderThickness="2">
                                <StackPanel>
                                    <TextBlock x:Name="MyTextBlock" Text="Control Template's TextBlock 1" />
                                    <ContentPresenter />
                                    <TextBlock Text="Control Template's TextBlock 2" />
                                </StackPanel>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Button x:Name="scottsButton" Style="{StaticResource MyButtonStyle}">
            <TextBlock Text="This Text should appear where the Control Template's ContentPresenter is located."/>
        </Button>
        <Button Grid.Row="1" Content="Click to hide visibility of TextBlock1" Click="Button_Click" />
    </Grid>
</Window>

背后代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        TextBlock tb = (TextBlock)this.scottsButton.Template.FindName("MyTextBlock", this.scottsButton);
        tb.Visibility = System.Windows.Visibility.Hidden;
    }
}

Would you be able to create an attached property (of tybe boolean or visibility) for the DataGridColumnHeader class and bind the Enabled or Visibility property of your Menu to that attached property?

http://www.deepcode.co.uk/2008/08/exposing-new-properties-for-control_15.html

Edit:


My thought is that an attached property is going to be simpler as you could just set the visibility in XAML, but I tried a quick test and I think the method you are trying to use should work just as well.

Menu myMenu = (Menu)this.myDataGrid.Template.FindName("menuColumnOptions", this.myDataGrid);
menu.Visibility = System.Windows.Visibility.Hidden;

If you're getting an error, could you show the code where you are trying to set the visibility in code behind? It sounds like you might be trying to access the DataGridColumnHeader's Template before it's been fully constructed (in which case moving your code to the Loaded event might solve your problem).

Edit 2:

<Window x:Class="TestApp11.MainWindow" 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:l="clr-namespace:TestApp11"
  xmlns:s="clr-namespace:System;assembly=mscorlib"
  Title="Window1" Height="500" Width="800">
    <Grid>
        <Grid.Resources>
            <Style x:Key="MyButtonStyle" TargetType="Button">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border BorderBrush="Red" BorderThickness="2">
                                <StackPanel>
                                    <TextBlock x:Name="MyTextBlock" Text="Control Template's TextBlock 1" />
                                    <ContentPresenter />
                                    <TextBlock Text="Control Template's TextBlock 2" />
                                </StackPanel>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Button x:Name="scottsButton" Style="{StaticResource MyButtonStyle}">
            <TextBlock Text="This Text should appear where the Control Template's ContentPresenter is located."/>
        </Button>
        <Button Grid.Row="1" Content="Click to hide visibility of TextBlock1" Click="Button_Click" />
    </Grid>
</Window>

Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        TextBlock tb = (TextBlock)this.scottsButton.Template.FindName("MyTextBlock", this.scottsButton);
        tb.Visibility = System.Windows.Visibility.Hidden;
    }
}
本王不退位尔等都是臣 2024-10-29 01:47:42

这就是我最终所做的。

我复制了样式并从此副本中删除了菜单。

然后,在代码中我只是使用以下方法设置它:

myDataGrid.ColumnHeaderStyle = (Style)FindResource("lclDataGridLockedColumnHeaders");

Here is what I ended up doing.

I copied the Style and removed the Menu from this Copy.

Then, in code I just set it using:

myDataGrid.ColumnHeaderStyle = (Style)FindResource("lclDataGridLockedColumnHeaders");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文