Change WPF DataGrid Column Header Style, Menu Visi

2019-07-28 09:42发布

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>

2条回答
家丑人穷心不美
2楼-- · 2019-07-28 10:11

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");

查看更多
虎瘦雄心在
3楼-- · 2019-07-28 10:15

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;
    }
}
查看更多
登录 后发表回答