在VisualStateManager中绑定到控件的属性 [英] Bind to Control's Property inside VisualStateManager

查看:95
本文介绍了在VisualStateManager中绑定到控件的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Stackoverflow上搜索了此问题,但我认为其他帖子均未涵盖此问题.

I searched for this Problem on Stackoverflow, but in my opinion the other Posts do not cover this question.

在我的自定义控件中,我正在使用Visual State Manager.在视觉状态管理器内部,有一个动画可以对元素的高度进行动画处理.当我尝试绑定到控件属性时,在启动时出现以下错误:

In my Custom Control i am using a Visual State Manager. Inside the Visual State Manager there is an Animation that Animates the Height of an Element. When i try to bind to the Controls Properties i get following Error on StartUp:

其他信息:找不到参考'RelativeSource FindAncestor,AncestorType = MyNameSpace.MyControl,AncestorLevel ='1''的绑定源.BindingExpression:Path = ActualHeight;DataItem = null;目标元素是"DoubleAnimation"(HashCode = 562002);目标属性是"To"(类型为"Nullable'1")

Additional information: Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType=MyNameSpace.MyControl, AncestorLevel='1''. BindingExpression:Path=ActualHeight; DataItem=null; target element is 'DoubleAnimation' (HashCode=562002); target property is 'To' (type 'Nullable`1')

我的控件如下:

<Style TargetType="{x:Type local:MyControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyControl}">
                <Grid x:Name="RootGrid" >
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="someElement"
                                                        Storyboard.TargetProperty="Height"
                                                        From="0"
                                                        To="{Binding RelativeSource={RelativeSource AncestorType=local:MyControl},  Path=CustomControlProperty}"
                                                        Duration="0:0:.7" />
...

我尝试了所有方式的绑定,但是似乎动画总是以自己为作用域.

I tried all ways of Bindings, but it seems that the Animations always takes itself as Scope.

再次感谢您的帮助.

推荐答案

我能够使用 BindingProxy /code> .我发现绑定代理是非直觉的.有时他们会在第一张照片上工作;这个经历了一点尝试和错误.而且,它们只是冰雹解决方案的一部分.

I was able to do this with a BindingProxy. I find binding proxies to be nonintuitive. Sometimes they work on the first shot; this one took a little trial and error. Also, they're a little bit of a hail-mary workaround.

XAML:

<Grid 
    x:Name="RootGrid"
    >
    <Grid.Resources>
        <!-- 
        When defined in ControlTemplate.Resources, this failed. 
        TemplateBinding failed too. 
        -->
        <local:BindingProxy
            x:Key="CustomControlPropertyProxy"
            Data="{Binding CustomControlProperty, RelativeSource={RelativeSource TemplatedParent}}"
            />
    </Grid.Resources>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CheckStates">
            <VisualState x:Name="Checked">
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="someElement"
                        Storyboard.TargetProperty="Height"
                        From="0"
                        To="{Binding Data, Source={StaticResource CustomControlPropertyProxy}}"
                        Duration="0:0:5"
                        />
                </Storyboard>

C#(被盗,不是第一次,来自此答案):

C# (stolen, not for the first time, from this answer):

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object),
                                     typeof(BindingProxy));
}

如果您最终将动画属性绑定到模板化父对象的多个属性,则这是XAML的另一种变体:

Here's another variant of the XAML, in case you end up binding animation properties to more than one property of the templated parent:

<Grid 
    x:Name="RootGrid"
    >
    <Grid.Resources>
        <local:BindingProxy
            x:Key="TemplatedParentProxy"
            Data="{Binding ., RelativeSource={RelativeSource TemplatedParent}}"
            />
    </Grid.Resources>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CheckStates">
            <VisualState x:Name="Checked">
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="someElement"
                        Storyboard.TargetProperty="Height"
                        From="0"
                        To="{Binding Data.CustomControlProperty, Source={StaticResource TemplatedParentProxy}}"
                        Duration="0:0:5"
                        />
                </Storyboard>

盲人小巷

排除了 TemplateBinding {RelativeSource TemplatedParent} 之后,我的下一个猜测是将 RootGrid.Tag 绑定到 CustomControlProperty ,并使用 To ="{Binding Tag,ElementName = RootGrid}" .那没有用.尽管intellisense在XAML设计器中了解 RootGrid ,但 Binding 在运行时找不到 RootGrid :

Blind Alleys

After ruling out TemplateBinding and {RelativeSource TemplatedParent}, my next guess was to bind RootGrid.Tag to CustomControlProperty and use To="{Binding Tag, ElementName=RootGrid}". That did not work. While intellisense knew about RootGrid in the XAML designer, the Binding couldn't find RootGrid at runtime:

<DoubleAnimation
    Storyboard.TargetName="someElement"
    Storyboard.TargetProperty="Height"
    From="0"
    To="{Binding Tag, ElementName=RootGrid, PresentationTraceSources.TraceLevel=High}"
    Duration="0:0:1"
    />

调试跟踪:

System.Windows.Data Warning: 67 : BindingExpression (hash=15221148): Resolving source 
System.Windows.Data Warning: 69 : BindingExpression (hash=15221148): Framework mentor not found
System.Windows.Data Warning: 67 : BindingExpression (hash=15221148): Resolving source  (last chance)
System.Windows.Data Warning: 69 : BindingExpression (hash=15221148): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Tag; DataItem=null; target element is 'DoubleAnimation' (HashCode=44950942); target property is 'To' (type 'Nullable`1')

治理FrameworkElement或FrameworkContentElement"爵士乐也是所有其他方法的基本问题.那就是绑定代理的用武之地:资源查找不受可视树父链的限制.

That "governing FrameworkElement or FrameworkContentElement" jazz is the essential problem with all of the other approaches as well. That's where binding proxies come in: Resource lookup isn't limited by that visual tree parent chain stuff.

这篇关于在VisualStateManager中绑定到控件的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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