如何在共享资源中重用 VisualState、VisualStateGroup 和 VsualStateManager? [英] How do I reuse VisualState, VisualStateGroup and VsualStateManager in shared resource?

查看:19
本文介绍了如何在共享资源中重用 VisualState、VisualStateGroup 和 VsualStateManager?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I created many buttons that it use the same VisualStateManager, VisualStateGroup and VisualState in my Windows Phone project. Then, I want to reuse all of them as the shared resources as the other type of an element such as margin, colors etc.

但我发现只有重用storyboard的方法,如果我能重用所有的VisualState会更好.

But I found only the way to reuse storyboard that it would be better if I can reuse all of the VisualState.

是否有可重用的 VisualState 的解决方案?

Is there solution of the reusable VisualState?

推荐答案

我找到的解决方案我在 Windows 10 UWP app 上测试过,我测试了几个选项,比如反序列化 XAML、克隆等,但最终我发现了以下内容是最好的解决方案:

The solution I found I tested on Windows 10 UWP app, I have tested several options like deserializing XAML, cloning, etc, but in the end I found the following is the best solution:

 <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.

This is the first trick, with this you can 'load' the VisualStateGroup several times.

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

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

This step is just copy and paste, and now in your controls simply add:

<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,而无需重复代码.

And with this you can share a VisualStateGroup among multiple controls without repeating code.

这篇关于如何在共享资源中重用 VisualState、VisualStateGroup 和 VsualStateManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆