【问题标题】:Set GroupStyle inside style on xaml在 xaml 上设置 GroupStyle 内部样式
【发布时间】:2015-12-19 07:17:56
【问题描述】:

我正在尝试为 ContexMenu 设置默认样式,并且我想在样式内将默认 GroupStyle 设置为 ContexMenu。像这样的:

<Setter Property="ItemsControl.GroupStyle">
    <Setter.Value>
       <GroupStyle>
          <...>
        </GroupStyle>
    </Setter.Value>
</Setter>

但编译器提示错误:在 ItemsControl 上找不到 GroupStyle。

但是,在代码中我可以简单地做:

ContextMenu contextMenu;
contextMenu.GroupStyle.Add(someSavedStyle);

如何在 xaml 中实现这一点?

提前致谢!

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    您可以使用附加属性来简化添加组样式:

    <Style TargetType="MenuItem">
        <Setter Property="b:GroupStyleEx.Append">
            <Setter.Value>
                <GroupStyle .. />
            </Setter.Value>
        </Setter>
    
        <!-- you can add as many as you like... -->
        <Setter Property="b:GroupStyleEx.Append">
            <Setter.Value>
                <!-- second group style -->
                <GroupStyle .. />
            </Setter.Value>
        </Setter>
    </Style>
    

    这是附加属性的代码:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace Util
    {
        public static class GroupStyleEx
        {
            public static readonly DependencyProperty AppendProperty
                = DependencyProperty.RegisterAttached("Append", typeof (GroupStyle), typeof (GroupStyleEx),
                                                      new PropertyMetadata(AppendChanged));
    
            public static GroupStyle GetAppend(DependencyObject obj)
            {
                return (GroupStyle) obj.GetValue(AppendProperty);
            }
    
            public static void SetAppend(DependencyObject obj, GroupStyle style)
            {
                obj.SetValue(AppendProperty, style);
            }
    
            private static void AppendChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var itemsControl = d as ItemsControl;
                if (itemsControl == null)
                    throw new InvalidOperationException("Can only add GroupStyle to ItemsControl");
    
                var @new = e.NewValue as GroupStyle;
                if (@new != null)
                    itemsControl.GroupStyle.Add(@new);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我解决这个问题的方法是创建一个从 ListBox 控件继承的新控件,该控件添加了一个可绑定的 DefaultGroupStyle:

          public class MyListBox : ListBox
          {
              public GroupStyle DefaultGroupStyle
              {
                  get { return (GroupStyle)GetValue(DefaultGroupStyleProperty); }
                  set { SetValue(DefaultGroupStyleProperty, value); }
              }
      
              // Using a DependencyProperty as the backing store for DefaultGroupStyle.  This enables animation, styling, binding, etc...
              public static readonly DependencyProperty DefaultGroupStyleProperty =
                  DependencyProperty.Register("DefaultGroupStyle", typeof(GroupStyle), typeof(MyListBox), new UIPropertyMetadata(null, DefaultGroupStyleChanged));
      
              private static void DefaultGroupStyleChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
              {
                  ((MyListBox)o).SetDefaultGroupStyle(e.NewValue as GroupStyle);
              }
      
              private void SetDefaultGroupStyle(GroupStyle defaultStyle)
              {
                  if (defaultStyle == null)
                  {
                      return;
                  }
      
                  if (this.GroupStyle.Count == 0)
                  {
                      this.GroupStyle.Add(defaultStyle);
                  }
              }
          }
      

      【讨论】:

        【解决方案3】:

        实际上,还可以做一些额外的工作:
        除了将ContexMenu 的模板设置为ItemsPresenter,您还可以将其设置为适合您数据的控件。在这种情况下,您可以将其设置为Menu。就像这样:

        <Style TargetType="ContextMenu">
             <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ContextMenu">
                                <Border>
                                    <Menu ItemsSource="{TemplateBinding ItemsSource}">
                                        <Menu.GroupStyle>
                                            <GroupStyle>
                                                <GroupStyle.ContainerStyle>
                                                    <Style TargetType="{x:Type GroupItem}">
                                                        <Setter Property="Template">
                                                           <Setter.Value>
                                                       <ControlTemplate TargetType="{x:Type GroupItem}">
                                                                    <StackPanel>
                                                                        <Border Background="Black">
                                                                           <ItemsPresenter/>
                                                                        </Border>
                                                                    </StackPanel>
                                                                </ControlTemplate>
                                                            </Setter.Value>
                                                        </Setter>
                                                    </Style>
                                                </GroupStyle.ContainerStyle>
                                            </GroupStyle>
                                        </Menu.GroupStyle>
                                        <Menu.ItemsPanel>
                                            <ItemsPanelTemplate>
                                                <StackPanel></StackPanel>
                                            </ItemsPanelTemplate>
                                        </Menu.ItemsPanel>
                                    </Menu>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>       
                </Style>
        

        现在,虽然GroupStyle 是只读的,但我们可以通过PropertyElement 设置它:-)

        为了得到ContexMenuMenuItem 的感觉,您可以调整MenuItem 的样式

        【讨论】:

        • 对于 ListBox 样式,您可以设置 ListBox 而不是 Menu。此解决方案也适用于其他样式
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-12
        • 1970-01-01
        • 2014-09-28
        • 1970-01-01
        相关资源
        最近更新 更多