首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在共享资源中重用VisualState、VisualStateGroup和VsualStateManager?

如何在共享资源中重用VisualState、VisualStateGroup和VsualStateManager?
EN

Stack Overflow用户
提问于 2015-08-10 14:06:30
回答 1查看 1.2K关注 0票数 4

我创建了许多按钮,它们在我的Windows Phone项目中使用相同的VisualStateManager、VisualStateGroup和VisualState。然后,我想要重用所有这些元素作为共享资源,作为其他类型的元素,如边距、颜色等。

但我发现只有重用故事板的方法是,如果我能重用所有的VisualState,那会更好。

有没有可重用VisualState的解决方案?

EN

回答 1

Stack Overflow用户

发布于 2015-08-10 18:05:30

我在Windows 10 UWP应用程序上测试的解决方案,我测试了几个选项,如反序列化XAML,克隆等,但最终我发现以下是最好的解决方案:

1-将VisualStateGroup设置为资源

代码语言:javascript
复制
 <Application.Resources>
   <DataTemplate x:Key="VisualStateTemplate">
    <Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup >
            <VisualState x:Name="NarrowView" >
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="Text.(RelativePanel.Below)" Value="Image" />
                    <Setter Target="Content.(RelativePanel.Below)" Value="Text" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="WideView">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="860" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="Text.(RelativePanel.RightOf)" Value="Image" />
                    <Setter Target="Content.(RelativePanel.Below)" Value="Image" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
  </Grid>
 </DataTemplate>
</Application.Resources>

这是第一个技巧,使用此技巧,您可以多次“加载”VisualStateGroup

2-实现附加属性以设置为VisualStateGroup的控件

代码语言:javascript
复制
public class VisualStateExtensions : DependencyObject
{
    public static void SetVisualStatefromTemplate(UIElement element, DataTemplate value)
    {
        element.SetValue(VisualStatefromTemplateProperty, value);
    }

    public static DataTemplate GetVisualStatefromTemplate(UIElement element)
    {
        return (DataTemplate) element.GetValue(VisualStatefromTemplateProperty);
    }

    public static readonly DependencyProperty VisualStatefromTemplateProperty = DependencyProperty.RegisterAttached("VisualStatefromTemplate", typeof(DataTemplate), typeof(VisualStateExtensions), new PropertyMetadata(null, VisualStatefromTemplateChanged));

    private static void VisualStatefromTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FrameworkElement frameworkElement)
        {               
            var visualStateGroups = VisualStateManager.GetVisualStateGroups(frameworkElement);
            if (visualStateGroups != null)
            {
                var template = (DataTemplate) e.NewValue;
                var content = (FrameworkElement) template.LoadContent();
                if (VisualStateManager.GetVisualStateGroups(content) is IList list)
                {
                    var source = list.Cast<VisualStateGroup>().ToList();
                    var original = source.First();

                    source.RemoveAt(0);

                    visualStateGroups.Add(original);
                }
            }
        }
    }
}

这一步只需复制和粘贴,现在只需在您的控件中添加:

3-添加附加属性

代码语言:javascript
复制
<UserControl x:Class="Example.MyUserControl1"...>
  <RelativePanel x:Name="Root" local:VisualStateExtensions.VisualStatefromTemplate="{StaticResource VisualStateTemplate}" >
</UserControl>

 <UserControl x:Class="Example.MyUserControl2"...>
   <RelativePanel x:Name="Root" local:VisualStateExtensions.VisualStatefromTemplate="{StaticResource VisualStateTemplate}" >
</UserControl>

这样,您就可以在多个控件之间共享一个VisualStateGroup,而无需重复编写代码。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31912603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档