在自定义控件中使依赖属性双向绑定

5

我有一个自定义控件,其中包含以下内容:

<TextBox Grid.Column="3" Text="{TemplateBinding SampleValue}" />

public static readonly DependencyProperty SampleValueProperty =
            DependencyProperty.RegisterAttached("SampleValue", typeof(string), typeof(IdattFilterBox), new PropertyMetadata(null));

public string SampleValue
        {
            get { return GetValue(SampleValueProperty) as string; }
            set { this.SetValue(SampleValueProperty, value); }
        }

在一个UserControl中,我声明了我的自定义控件,其XAML如下:
<my:SampleBox SampleValue="{Binding SampleValue, Mode=TwoWay}" />

并且像这样使用ViewModel:

public string SampleValue
        {
            get
            {
                return this.sampleValue;
            }

            set
            {
                this.sampleValue = value;
            }
        }

我不关心VM上的INotifyPropertyChanged(所以不要告诉我它是什么 :))。 目前,它可以像我在VM中设置的那样,在文本框中显示文本。但是当我修改这个文本时,它没有返回到VM。

我该怎么办?我猜我得在自定义控件内编写一些代码?我应该处理TextBox PART并捕获LostFocus吗?还是使用TemplateBinding如何工作?

4个回答

7

TemplateBinding 只支持 OneWay 模式。

如果您正在使用 Silverlight 4,您可以尝试以下方法:

{Binding SampleValue, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}

4

TemplateBinding本质上是单向的。您需要使用Mode=TwoWaySource={Binding RelativeSource={RelativeSource TemplatedParent}}绑定。


2

也许您想使用 DependencyProperty.Register 代替 DependencyProperty.RegisterAttached?

鉴于您的标题,您可能不想创建附加属性。

编辑:

从您提供的代码示例中,我不确定您实际要做什么。

要获得双向绑定,您可能有两个方向

  • 添加 INotifyPropertyChanged(由于某些原因,您不想这样做)

  • 处理 new PropertyMetadata(null) 而不是 null,在那里提供更改事件的处理程序(以及如有需要的默认值),并在那里使用 NewValue 进行所需操作。

如果可能,请更新问题,以便更容易理解哪个控件具有什么以及谁如何绑定。(更多 XAML 应该可以解决)

还请注意,除非失去焦点,否则 TextBox 不会触发事件。


是的,你说得对,我不需要附加属性。但是这仍然没有解决问题。问题是如何将输入到文本框中的值传递回控件的使用者? - katit

0

首先要添加Source绑定,以便显示您正在将元素绑定到源元素的上下文中。
尝试使用类似以下内容的代码:

<my:SampleBox SampleValue="{Binding SampleValue, Source={StaticResource someViewModel}, Mode=TwoWay}" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接