我遇到了Binding问题。由于RelativeSource
需要可视化树向上移动并找到所需的祖先,因此您只能在UIElement
上使用它,但我正在尝试对非RelativeSource
绑定UIElement,例如ValidationRule,你们都知道它不在VisualTree
内,也不在UIElement
内。正如您所料,绑定会中断。无法找到RelativeSource
因为我说没有VisualTree
或LogicalTree
可用。我需要让它工作。
以下是XAML的一个示例:
<StackPanel DataContext{Binding}>
<Grid>
<ContentControl Content{Binding MVPart1>
<TextBox>
<TextBox.Text>
<Binding Path="VMPart1Property1">
<Binding.ValidationRules>
<my:MyValidationRule>
<my:ValidationRule.DOC>
<my:DepObjClass DepProp={Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StackPanel}}}/>
</my:ValidationRule.DOC>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</ContentControl>
</Grid>
</StackPanel>
所以基本上MyValidationRule派生自ValidationRule类,但那不是UIElement,也不是DependencyObject,因此我必须创建一个派生自DependencyObject的类,名为DepObjClass,以便能够记下xaml绑定表达式。
这是代码:
public class MyValidationRule : ValidationRule
{
public DepObjClass DOC
{
get;
set;
}
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
string text = value as string;
if (!string.IsNullOrEmpty(text))
{
return new ValidationResult(true, string.Empty);
}
return new ValidationResult(false, "Not working blahhh");
}
}
public class DepObjClass : DependencyObject
{
public object DepProp
{
get
{
return (object)GetValue(DepPropProperty);
}
set
{
SetValue(DepPropProperty, value);
}
}
public static DependencyProperty DepPropProperty
= DependencyProperty.Register(typeof(object), typeof(DepObjClass)......);
}
现在总结一下。 MyValidatonRule不是UIElement而不是DependencyObject,但它有一个类型的属性,因此xaml绑定表达式编译的原因。
当我运行应用程序时,绑定本身无法正常工作,因为无法找到StackPanel,因为ValidationRule没有VisualTree,也没有我的验证规则参与逻辑或Visual Tree。
问题是如何使这样的案例工作,如何从非UIElement中找到StackPanel,例如我的ValidationRule?
我道歉我的代码没有加入,但我希望你能理解我想要做的事情。 我给你们50分给出正确答案。
答案 0 :(得分:3)
您可以执行以下操作:
创建一个派生自Freezable的帮助程序组件,并为要绑定的内容定义DependencyProperty。
创建一个ValidationRule,其中包含一个获取辅助组件对象的属性,类似于您已经完成的操作。
在对象的Resources中声明一个helper组件的实例,该实例可以绑定到您想要绑定的任何内容。 Freezable及其派生类继承了声明其资源的任何控件的绑定上下文(逻辑树中的位置),因此您可以创建绑定。
在声明ValidationRule时,使用{StaticResource}将帮助程序组件分配给ValidationRule中的属性。 StaticResource在没有绑定上下文的情况下工作,只要资源在使用之前声明即可。
XAML看起来像这样:
<StackPanel>
<StackPanel.Resources>
<my:Helper x:Key="helper" ValProperty="{Binding}"/>
</StackPanel.Resources>
<Grid>
<TextBox DataContext="{Binding MVPart1}">
<TextBox.Text>
<Binding Path="VMPart1Property1">
<Binding.ValidationRules>
<my:MyValidationRule Helper="{StaticResource helper}"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</StackPanel>