WPF依赖性属性已更改,但未在绑定中实现

问题描述 投票:0回答:1

我遇到了here之前发布的一个问题。我仍在为这个问题而苦苦挣扎,因此我尝试在较小的代码设置中对其进行细分。

问题:

我有一个依赖项属性绑定到视图模型,它不会使用更改后的值@ construction time来更新视图模型。

绑定似乎是正确的,因为在应用程序启动后更改XAML中的值(依赖于xaml热重载)确实使用更改来更新视图模型。

我可以使用以下设置重现该问题:

MainWindow:

<Grid>
    <local:UserControl1 
        SomeText="My changed text" 
        DataContext="{Binding UserControlViewModel}"/>
</Grid>

MainViewModel:

public class MainViewModel
{
    public UserControlViewModel UserControlViewModel { get; set; }
    public MainViewModel()
    {
        UserControlViewModel = new UserControlViewModel();
    }
}

UserControl:

<UserControl.Resources>
    <Style TargetType="local:UserControl1">
        <Setter Property="SomeText" Value="{Binding MyText, Mode=OneWayToSource}"></Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <TextBlock Text="{Binding MyText}"></TextBlock>
</Grid>

后面的UserControl代码:

public static readonly DependencyProperty SomeTextProperty = DependencyProperty.Register(
    nameof(SomeText),
    typeof(string),
    typeof(UserControl1),
    new PropertyMetadata("default text", PropertyChangedCallback));

public string SomeText { get; set; }

private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // first and only update: 'default text' => 'My changed text'
}

public UserControl1()
{
    InitializeComponent();
}

UserControl视图模型:

public class UserControlViewModel
{
    // Setter is called with 'default text'
    // AFTER the property changed callback is triggered with updated text
    public string MyText { get; set; }
}

[当我运行该应用程序时,显示文本'默认文本',而我期望'我更改的文本'。

[然后在XAML中更改SomeText属性时,再次看到更改后的回调触发,因此,我看到视图模型设置器得到更新。这次with更改后的值。因此,绑定似乎可以正常工作,但是在启动期间,绑定无法使用(已知)更改后的值来更新视图模型。

有人可以解释导致此问题的原因吗?有办法解决这个问题吗?

更新

我刚刚发现,当我更改XAML时(使用热重装),更新顺序为:

  • << [first设置了视图模型的设置器
  • then触发OnPropertyChanged回调。
  • 结果是
  • 更改后的值
  • 显示在UI上
与施工时发生的情况相反。那么顺序是:

    触发OnPropertyChanged回调
  • 已设置视图模型的设置器。
  • 结果是
  • default
值显示在UI上(如原始问题中所述)这真的很奇怪。因为当Property Changed回调触发时(在启动过程中),我可以将DependencyObject强制转换回UserControl并检查其数据上下文。数据上下文当时为

null

我之前的热重装实验证明,绑定最终可以完美地工作。

    因此,步骤1是将文本“我更改的文本”设置为依赖项属性。
  • 步骤2是将视图模型作为数据上下文连接到MyUserControl
  • 第3步是解除绑定的绑定,在这种情况下,绑定(onewaytosource)得到它的初始同步,但是使用
  • 旧值
对我来说,这似乎是WPF中的错误。
c# wpf mvvm dependency-properties
1个回答
0
投票
您为用例使用了错误的绑定模式。

当指定OneWayToSource时,由于源是MyText属性,因此只允许数据从文本框流到ViewModel中的属性。

尝试删除Mode = OneWayToSource,或者如果您想同时从View和ViewModel中更新文本,请使用TwoWay。 (IIRC TwoWay是TextBox控件的默认模式。)>

而且,您的ViewModel是否实现了INotifyPropertyChanged接口以支持绑定?

解释不同模式的小结在this SO答案中>

© www.soinside.com 2019 - 2024. All rights reserved.