【问题标题】:Change WPF DataGrid Column Header Style, Menu Visibility in Code Behind?更改 WPF DataGrid 列标题样式,代码隐藏中的菜单可见性?
【发布时间】:2011-03-14 19:32:20
【问题描述】:

我有以下“样式”(在 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>

【问题讨论】:

    标签: wpf datagrid wpfdatagrid


    【解决方案1】:

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

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

    编辑:

    我的想法是附加属性会更简单,因为您可以在 XAML 中设置可见性,但我尝试了一个快速测试,我认为您尝试使用的方法应该也能正常工作。
    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;
        }
    }
    

    【讨论】:

    • 我想。我只是不太确定“如何”?我希望我可以从 Menu 元素 (x:Name="menuColumnOptions") 获得 Visibility 属性。这不是最简单的方法吗? (如果可能的话……)
    • @Shayne,我会留给你来决定最简单的方法是你的场景,但我相信你应该能够像你一样使用 Template.FindName(...)在你的问题中提出建议。我尝试使用 ControlTemplate 对资源样式中的按钮集进行快速测试。然后在另一个按钮的单击事件处理程序中,我能够访问我的 ControlTemplate 中的命名 TextBlock 并将其更改为 Text。我已经编辑了我的答案,以使用我认为您需要使用的确切代码行,希望对您有所帮助!
    • 我试图将其“隐藏”在按钮单击事件的处理程序中。不幸的是,FindName 方法返回 NULL。我很乐意尝试您的其他建议,但这是我从事过的第一个 WPF 应用程序,我不知道从哪里开始。知道为什么此时它会为空吗?我的情况和你的测试之间的区别是,这个 Style 是通过“ColumnHeaderStyle”属性静态分配给 DataGrid 的,正如我在原始帖子中指出的那样,但我不明白为什么这很重要(尽管它必须)? ?
    • 现在我考虑我的最后一句话。当然这很重要,这个样式/菜单必须分配给每个列标题,对吧?所以,我将不得不在每一列上改变它(对于每一列?)....我是否朝着正确的方向前进?
    • @Scott 我需要采取类似的方法吗? stackoverflow.com/questions/4030764/…
    【解决方案2】:

    这就是我最终要做的。

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

    然后,在代码中我只是使用:

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

    【讨论】:

      猜你喜欢
      • 2013-12-01
      • 2014-05-02
      • 2010-11-07
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 2018-03-20
      相关资源
      最近更新 更多