我有一个我定义的附加属性。
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,指出:&#34; Value不在预期的范围内。&#34;
如果相反,我会替换&#34;(Grid.Row)&#34;对于我的财产,没有抛出异常。
答案 0 :(得分:1)
对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对象创建为唯一的子对象,则抛出异常。
答案 1 :(得分:0)
为了调试这个,我想可能我的语法错误的命名空间,所以在我的xaml资源部分,我添加了这个:
<Binding x:Key="yuck" Path="(controls:StateManager.VisualState)" ElementName="pageRoot" />
当我检查属性路径的路径时,它与我指定的完全一样。
作为一种解决方法,我目前正从后面的代码中获得这样的绑定:
BindingOperations.SetBinding(ct, StateManager.VisualStateProperty,
Resources["yuck"] as Binding);
这似乎有效,但是为什么我不能从后面的代码创建对象?
<强>更新强> 这适用于Windows 8应用程序,但现在在UWP上出错。
为了让它在UWP上工作,我不得不将数据绑定到我的ParentGrid的Tag。
<Grid x:Name="ParentGrid" Tag="{Binding ElementName=pageRoot, Path=(controls:StateManager.VisualState)}">
然后我可以创建一个绑定到标签,如下所示:
var pp3 = new PropertyPath("Tag");
barf = new Binding() { Path = pp3, Source = ParentGrid };