c#-绑定到VisualStateManager中的控件的属性

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

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

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

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

再次感谢您的帮助.

解决方法:

我能够做到这一点with a BindingProxy.我发现绑定代理是非直觉的.有时他们会在第一枪上工作;这个经历了一点尝试和错误.而且,它们只是冰雹解决方法.

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#(被盗,不是第一次,是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的另一种变体:

<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,但绑定在运行时找不到RootGrid:

<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”爵士乐也是所有其他方法的基本问题.那就是绑定代理的来源:资源查找不受可视树父链的限制.

上一篇:BZOJ 2049: [Sdoi2008]Cave 洞穴勘测——LCT


下一篇:c#-使用数据绑定访问DataTemplate内部的WPF组件