OneWayToSource困境

sno*_*hog 2 wpf xaml wpf-4.0

我正在使用OneWayToSource绑定,似乎它始终将我的source属性设置为null.为什么会这样?它给我带来了麻烦,因为我需要源属性中的target属性的值而不是null.

这是我的代码:

MyViewModel.cs:

public class MyViewModel
{
    private string str;

    public string Txt
    {
        get { return this.str; }
        set { this.str = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

MainWindow.cs:

public MainWindow()
{
    InitializeComponent();
    MyViewModel vm = new MyViewModel();
    vm.Txt = "123";
    this.DataContext = vm;
}
Run Code Online (Sandbox Code Playgroud)

MainWindow.xaml:

<Window x:Class="OneWayToSourceTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:OneWayToSourceTest">
      <Grid>
        <local:MyButton Content="{Binding Path=Txt, Mode=OneWayToSource}"/>
      </Grid>
 </Window>
Run Code Online (Sandbox Code Playgroud)

MyButton.cs:

public class MyButton : Button
{
    public MyButton()
    {
        this.Content = "765";
    }
}
Run Code Online (Sandbox Code Playgroud)

目标属性是MyButton.Content.源属性是MyViewModel.Txt.该Txt属性应设置为"765",但它为null.

为什么我会收到null而不是765?

编辑:

请看一下内部MyButton构造函数.实际上如果你会使用简单TwoWay它将工作.我测试了它,它与构造函数中设置的内容无关.它的OneWayToSource结合我想.

现在解释我是如何使用TwoWay绑定的,我确实通过调用setvalue方法在构造函数中设置了dp的值但是然后在包装器中或更好地说getter和setter我没有提供任何setter因此为什么我让我TwoWay看起来像它OneWayToSource.我做了它来测试它的构造函数是否有错.我认为viewmodel中的属性值为765,这就是我对TwoWay绑定的意思.我刚测试它是否是控件构造函数.在构造函数中设置一个值就可以了.

通过隐藏setter我的意思是这个 集{}

Rac*_*hel 9

Content属性只能设置为单个值,并且您使用绑定替换值"756".

正如我在回答您的其他问题时向您指出的那样,WPF按此顺序运行代码:

  • 正常 - 构造函数在这里运行
  • 的DataBind
  • 给予
  • 加载

所以首先要做的MainWindow就是运行Constructor.这将创建调用Button的构造函数的按钮,并设置Button.Content为"765".

但是在XAML中Button,您指定了一个不同的Content属性 - 绑定.因此,您的按钮对象被创建,Content属性设置为"765",然后Content属性设置为{Binding Path=Txt, Mode=OneWayToSource}.

这与做类似的事情是一样的:

var b = new MyButton();
b.Content = "756";
b.Content = new Binding(...); 
Run Code Online (Sandbox Code Playgroud)

您正在更换Content房产.

(从技术上讲,最后一行应该是b.SetBinding(MyButton.ContentProperty, new Binding(...));正确绑定值,但是我使用更基本的语法来更容易理解问题.)

循环的下一步是数据绑定,因此将Content评估对属性的绑定.

由于它是一个OneWayToSource绑定,因此该属性仅在更改源元素时更新它,并且因为这是第一次评估绑定,所以它将源设置为默认值,DependencyProperty因此它们是同步的.

对于Button.Content依赖项属性,默认值为null,因此您的源元素设置为null.

您没有看到TwoWay绑定的这种行为,因为DP从绑定中获取它的值而不是使用默认值.

如果您在设置绑定后设置了值,例如在Loaded按钮的情况下,您会看到在设置Button时正确更新了源属性Content

void MyButton_Loaded(object sender, EventArgs e)
{
    ((Button)sender).Content = "756";
}
Run Code Online (Sandbox Code Playgroud)

最后,如果您尝试Content从自定义控件设置属性的默认值,则需要覆盖该MetaData属性,如下所示:

// Note that this is the static constructor, not the normal one
static MyButton()
{
    ContentProperty.OverrideMetadata(typeof(MyButton), 
        new FrameworkPropertyMetadata("756"));
}
Run Code Online (Sandbox Code Playgroud)

这将使它成为Content属性的默认值"756"而不是null