我有一个定义的附加属性。

namespace Controls
{
public class StateManager : DependencyObject
{
    public static string GetVisualState(DependencyObject obj)
    {
        return (string)obj.GetValue(VisualStateProperty);
    }

    public static void SetVisualState(DependencyObject obj, string value)
    {
        obj.SetValue(VisualStateProperty, value);
    }

    // Using a DependencyProperty as the backing store for VisualStateProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty VisualStateProperty =
        DependencyProperty.RegisterAttached("VisualState", typeof(string), typeof(StateManager),
        new PropertyMetadata(null,
            (s, e) => {
                var stateName = (string)e.NewValue;
                var ctrl = s as Control;
                if (ctrl == null) throw new InvalidCastException("You can only attach VisualState properties to Controls");

                if (!string.IsNullOrEmpty(stateName))
                    VisualStateManager.GoToState(ctrl, stateName, true);
            }));
}
}


我可以像这样在XAML中绑定到此属性:

<controls:TitleStrip
    controls:StateManager.VisualState=
          "{Binding (controls:StateManager.VisualState), ElementName=pageRoot}"
    Grid.Column="1"/>


现在,我需要在代码中动态创建一个绑定到同一属性,因此我尝试了以下操作:

var pp = new PropertyPath("(controls:StateManager.VisualState)");
var binding = new Binding() { Path= pp, Source=this };
BindingOperations.SetBinding(ct, StateManager.VisualStateProperty, binding);


不幸的是,设置绑定的Path属性会引发ArgumentException声明:“值不在预期范围内。”

相反,如果将“(Grid.Row)”替换为我的属性,则不会引发任何异常。

最佳答案

在Windows 10上的进一步研究表明,如果尝试将附加属性Controls.StateManager.VisualState绑定到控件ct上具有相同名称的附加属性上,则这似乎可以在C#代码中运行:

string bindingxaml =
@"<ResourceDictionary
xmlns:controls=""using:Controls""
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
>
<Binding x:Key=""binding"" Path=""(controls:StateManager.VisualState)"" />
</ResourceDictionary>";

ResourceDictionary dict = XamlReader.Load(bindingxaml) as ResourceDictionary;
Binding binding = dict["binding"] as Binding;
binding.Source = this;
BindingOperations.SetBinding(ct, StateManager.VisualStateProperty, binding);


奇怪的是,如果不将其包含在ResourceDictionary中,则会引发异常,并尝试将Binding对象创建为唯一的子对象。

09-27 00:42
查看更多