在xaml上的样式中设置GroupStyle

时间:2012-03-07 09:33:30

标签: wpf xaml

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

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

但编译器说错误:它无法在ItemsControl上找到GroupStyle。

但是,在代码中我可以做到:

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

我如何在xaml中实现这一目标?

提前致谢!

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

实际上,通过一些额外的工作可以做到:
您可以将其设置为适合您数据的控件,而不是将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进行设置: - )

为了准确了解MenuItem ContexMenu的感受,您可以调整MenuItem的风格

答案 2 :(得分:0)

我解决这个问题的方法是创建一个新的控件,它继承自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);
            }
        }
    }