【发布时间】:2017-11-26 00:19:48
【问题描述】:
我有一个带有两个 DependencyProperties 的自定义控件。一种类型对象,允许用户像其他控件一样添加自定义内容,以及一种用于文本框的类型字符串:
public object NoResultContent
{
get { return (object)GetValue(NoResultContentProperty); }
set { SetValue(NoResultContentProperty, value); }
}
public static readonly DependencyProperty NoResultContentProperty =
DependencyProperty.Register("NoResultContent", typeof(object), typeof(AdvancedAutoCompleteBox), new PropertyMetadata(null));
public string FilterText
{
get { return (string)GetValue(FilterTextProperty); }
set { SetValue(FilterTextProperty, value); }
}
public static readonly DependencyProperty FilterTextProperty =
DependencyProperty.Register("FilterText", typeof(string), typeof(AdvancedAutoCompleteBox),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal,
new PropertyChangedCallback(OnFilterTextPropertyChanged), new CoerceValueCallback(CoerceText),
true, UpdateSourceTrigger.PropertyChanged));
ControlTemplate 看起来像:
<ControlTemplate
TargetType="{x:Type local:SpecialBox}">
<StackPanel>
<TextBox
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FilterText}" />
<ContentPresenter
ContentSource="NoResultContent" />
</StackPanel>
</ControlTemplate>
我是这样使用的:
<Controls:SpecialBox
Name="Box">
<Controls:SpecialBox.NoResultContent>
<Button
Content="Add value"
CommandParameter="{Binding ElementName=Box, Path=FilterText}"
Command="{Binding AddProject}" />
</Controls:SpecialBox.NoResultContent>
</Controls:SpecialBox>
<TextBlock Text="{Binding ElementName=Box, Path=FilterText}" />
Window 的 DataContext 设置为我的 ViewModel。所以绑定到ICommand 有效。提供一个常量字符串作为 CommandParameter 将根据需要将其传递给 ICommand。
CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"
将“添加值”传递给我的 ICommand 实现。
ElementName 绑定,如上所述和以下代码 CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Controls:SpeicalBox}, Path=FilterText}"
不起作用。找不到源。
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FilterText}"
不抛出警告,但总是返回 null。
更多信息:
每次更改都会触发我的 dp 的 OnFilterTextPropertyChanged 事件。所以这个值是可用的,这就是为什么 TextBlocks 文本绑定到 SpecialBox 工作得很好。
在我的 ViewModel 上为 FilterText 值提供第二个属性是一种解决方法,但我如何能够从第二个属性访问本地 dp?
【问题讨论】:
-
“不工作”是什么意思?你的命令得到的命令参数是什么?
-
绑定总是返回null。将常量字符串值作为参数写入效果很好
-
首先,您需要确定
Button.CommandParameter是否实际上是null(错误也可能是错误的ICommand实现)。例如。添加Button.Click处理程序,设置断点并检查Button。 -
ICommand 运行良好。实际的问题是,任何元素或相对绑定都不起作用:Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Controls.SpecialBox', AncestorLevel='1''
-
好的。在这种情况下,您提供的代码是您正在使用的实际模板(特别是
ContentPresenter)?另外,您使用的是什么框架版本?
标签: c# wpf mvvm data-binding