当我以编程方式更改用户控件时,如何让数据绑定双向工作?

Posted

技术标签:

【中文标题】当我以编程方式更改用户控件时,如何让数据绑定双向工作?【英文标题】:How do I get data binding to work both ways, when I'm programmatically changing the user control? 【发布时间】:2019-12-19 12:42:48 【问题描述】:

我有一个 WPF 应用程序,它使用用户设置,并将其绑定到 <TextBox>,如下所示:

<Window x:Class="SampleApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    <Grid>
        <TextBox x:Name="textbox" Text="Binding Source=StaticResource Settings, Path=Default.Folder"/>
    </Grid>
</Window>

App.xaml 如下所示:

<Application x:Class="SampleApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:properties="clr-namespace:SampleApp.Properties"
             ShutdownMode="OnExplicitShutdown"
             Startup="Application_Startup">
    <Application.Resources>
        <properties:Settings x:Key="Settings"/>
    </Application.Resources>
</Application>

这是 App.xaml.cs:

public partial class App : Application

    public App()
    
    

    private void Application_Startup(object sender, StartupEventArgs e)
    
        new MainWindow().ShowDialog();
    

这在一个方面非常有效:当窗口显示时,我的 TextBox 总是显示 MySetting 的内容。

相反的方法并不如我所愿。 的作用是当用户手动写入文本框时。

不起作用的是,当我以编程方式对 TextBox 进行更改时,如下所示:

textbox.Text = folderBrowserDialog.SelectedPath;

在这种情况下,MySetting 在用户输入文本框之前不会更新。

我目前的解决方案是这样做:

Properties.Settings.Default.MySetting = textbox.Text;

但它破坏了双向数据绑定的意义。

我应该怎么做才能让数据绑定双向工作,即使我以编程方式更改用户控件?

【问题讨论】:

你确定你使用的是StaticResource Settings吗?使用x:Static local:Properties.Settings 会更典型。您真的在这里发布了真实代码吗? IE。直接从minimal reproducible example 复制/粘贴?请确保您包含一个实际 minimal reproducible example? @PeterDuniho。我是 WPF 的初学者。我只是按照MSDN blog 中的内容进行操作。我不知道还有其他方法可以实现这一点,抱歉。无论如何,我已经更新了我的问题。 【参考方案1】:

但它破坏了双向数据绑定的意义。

不,不是。

双向绑定的要点是,当代码修改源属性时,UI的目标属性更新,用户修改目标属性时,源属性更新。

双向绑定绝对不存在,因此您可以通过编程方式为目标属性分配一个值,并将其反映在您可以拥有并且应该设置的源属性中。

编写 WPF 代码的人很少需要命名或与 XAML 中定义的 UI 元素进行交互。而当这种情况发生时,应该实现用户界面功能,例如拖放选择、拖放、按键处理等。

换一种说法:在 MVVM 范式中,视图模型数据结构是唯一非 UI 代码应该处理的东西。绑定机制在业务逻辑(由视图模型(以及可选的其背后的模型)表示)和用户界面(由 XAML 表示)之间提供中介。

确实,通常如果您要显式设置目标属性,它会丢弃绑定,导致它根本不起作用。

因此,执行此操作的正确方法是,在代码隐藏中,MySetting 属性交互。如果要更新显示给用户的值,则需要更改绑定到该值的代码隐藏属性。

【讨论】:

总结一下:不是textbox.Text = folderBrowserDialog.SelectedPathProperties.Settings.Default.MySetting = folderBrowserDialog.SelectedPath,数据绑定会相应地更新TextBox。明白了,谢谢。 没错。对不起,我在上面没有更明确。

以上是关于当我以编程方式更改用户控件时,如何让数据绑定双向工作?的主要内容,如果未能解决你的问题,请参考以下文章

vue数据双向绑定原理

当通过网络接收的数据更改属性时,如何将控件绑定到属性更改?

WinForm 双向数据绑定

自定义用户控件的 DependencyProperty 绑定未在更改时更新

以编程方式更改值时触发Dojo Select onChange事件触发

如何在数据绑定值更改时更新图像?