【问题标题】:Sharing styles between several GridView controls在多个 GridView 控件之间共享样式
【发布时间】:2013-02-09 06:12:25
【问题描述】:

我需要在整个应用程序中使用相同的视觉样式设置多个GridView。此样式包括自定义ItemsPanel 属性以及GroupStyle 属性。

我的问题是GridViewGroupStyle 属性不是依赖属性。所以我想写的代码(见下文)不起作用。

您知道在多个GridViews 之间共享样式(包括GroupStyle)的简洁方法吗?

我唯一能想到的是使用GroupStyleSelector,但它有点愚蠢,因为没有选择:它总是使用相同的GroupStyle。此外,我怀疑它不会在设计时反映在 VS & Blend 中。

我想使用的代码:

<GridView 
     ItemsSource="..."
     ItemTemplate="..."
     Style="{StaticResource MainMenuStyle}"/>

<Style TargetType="GridView" x:Key="MainMenuStyle">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            ...
        </Setter.Value>
    </Setter>
    <Setter Property="GroupStyle">
        <Setter.Value>
            <GroupStyle>
                ...
            </GroupStyle>
        </Setter.Value>
    </Setter>
</Style>

【问题讨论】:

  • 您能否按照您想要的方式将您的网格布局设置为UserControl 并公开诸如“ItemsSource”之类的依赖属性,以便您可以将其应用于实例,以便您回收相同的模板,但仍填充不同的数据?
  • 是的,看起来像是查看答案的方式。还没有了解UserControl,似乎是开始的好时机。

标签: xaml gridview windows-8 winrt-xaml


【解决方案1】:

我有一个神奇的快乐解决方案。

您可以创建在样式中设置的自定义附加属性,并在内部设置后设置 GridView 上的 GroupStyle 属性。

附加属性:

// Workaround for lack of generics in XAML
public class GroupStyleCollection : Collection<GroupStyle>
{
}

public class GroupStyleHelper
{
    public static ICollection<GroupStyle> GetGroupStyle(ItemsControl obj)
    {
        return (ICollection<GroupStyle>)obj.GetValue(GroupStyleProperty);
    }

    public static void SetGroupStyle(ItemsControl obj, ICollection<GroupStyle> value)
    {
        obj.SetValue(GroupStyleProperty, value);
    }

    public static readonly DependencyProperty GroupStyleProperty =
        DependencyProperty.RegisterAttached(
            "GroupStyle",
            typeof(ICollection<GroupStyle>),
            typeof(GroupStyleHelper),
            new PropertyMetadata(null, OnGroupStyleChanged));

    private static void OnGroupStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ItemsControl itemsControl = d as ItemsControl;
        if (itemsControl == null)
            return;

        RefreshGroupStyle(itemsControl, GetGroupStyle(itemsControl));
    }

    private static void RefreshGroupStyle(ItemsControl itemsControl, IEnumerable<GroupStyle> groupStyle)
    {
        itemsControl.GroupStyle.Clear();

        if (groupStyle == null)
            return;

        foreach (var item in groupStyle)
        {
            itemsControl.GroupStyle.Add(item);
        }
    }
}

XAML 样式:

    <Style TargetType="ItemsControl">
        <Setter Property="GroupStyleTest:GroupStyleHelper.GroupStyle">
            <Setter.Value>
                <GroupStyleTest:GroupStyleCollection>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock FontWeight="Bold" FontSize="15" Text="{Binding Path=Name}" Foreground="HotPink"/>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </GroupStyleTest:GroupStyleCollection>
            </Setter.Value>
        </Setter>
    </Style>

免责声明:我在 WPF 而不是 WinRT 中对此进行测试,但据我所知,它的工作原理应该相同。这也是我使用 ItemsControl 而不是 GridView 的原因,但属性仍然是 ItemsControl.GroupStyle。

【讨论】:

    【解决方案2】:

    我有一个解决方案,这肯定会根据您的问题起作用,但是您应该决定是否在您的情况下使用它。

    • 如果您必须在整个项目中创建相同样式的控件,那么您应该创建一个公共文件夹并在该文件夹中 创建一个“自定义用户控件”并应用您的所有样式和 随心所欲地定制它。

    • 之后,当您需要在同一控件(任何网格控件)上应用相同类型的样式时,只需添加该自定义用户
      控件而不是预定义控件

    通过这样做,您还将实现 MVC 架构和模块化。

    我正在使用 XAML 在 C# 中开发 Windows 8 Metro 应用程序,并且每当我想要这种方法时,我总是使用这个解决方案并且它总是有效...

    要创建自定义用户控件,您应该使用 visual studio & 在那个 右键单击项目 -> 添加 -> 新项目 -> 用户控件

    (抱歉,如果您在此处找不到您的解决方案,但我认为这可能会有所帮助...)

    【讨论】:

    • 谢谢,看起来与其他答案相同。我会尽快试一试。
    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2014-07-09
    • 2019-10-02
    • 2019-03-17
    • 1970-01-01
    相关资源
    最近更新 更多