繁体   English   中英

WPF 如何使用 MVVM 模式将值正确绑定到 TextBox

[英]WPF how to bind value to TextBox correclty with MVVM pattern

我目前正在试验 WPF。 我使用 Visual Studio 的 Windows Template Studio 创建了一个演示项目。

现在我想添加一个应该由 MVVM 模式自动保存的文本框。 我将以下 XAML 添加到我的设置页面。

<TextBlock
   Style="{StaticResource BodyTextStyle}"
   Text="Default Page" />
<TextBox Text="{Binding DefaultPage}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="TextChanged">
            <i:InvokeCommandAction Command="{Binding SetDefaultPageCommand}" CommandParameter="{Binding DefaultPage}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

SettingsViewModel我添加了以下几行:

private readonly IDefaultPageService _defaultPageService;
private string _defaultPage;
public ICommand SetDefaultPageCommand => _setDefaultPageCommand ?? (_setDefaultPageCommand = new RelayCommand<string>(OnSetDefaultPage));

public string DefaultPage
{
    get { return _defaultPage; }
    set { Set(ref _defaultPage , value); }
}

private void OnSetDefaultPage(string defaultPage)
{
    _defaultPageService.SetDefaultPage(defaultPage);
}

要保存的服务实现为:

public class DefaultPageService : IDefaultPageService
{
    public DefaultPageService()
    {
    }

    public void InitializeDefaultPage()
    {
        var theme = GetDefaultPage();
        SetDefaultPage(theme);
    }

    public void SetDefaultPage(string defaultPage)
    {
        App.Current.Properties["DefaultPage"] = defaultPage.ToString();
    }

    public string GetDefaultPage()
    {
        if (App.Current.Properties.Contains("DefaultPage"))
        {
            var defaultPage = App.Current.Properties["DefaultPage"].ToString();
            return defaultPage;
        }

        return "https://google.com";
    }

}

保存我的新字符串有效,但不幸的是,在实际绑定属性更改其值之前调用了我的命令。 我已经尝试了一堆不同的 TextBox 事件,例如KeyUpKeyDown 我发现唯一有效的事件是LayoutUpdated ,但这个事件被 GUI 一遍又一遍地触发,所以我很确定有更好的方法。

有人知道我该如何解决这个问题吗?

添加绑定选项

UpdateSourceTrigger=PropertyChanged

class ViewModel
{
    private string _defaultPage;
    public string DefaultPage
    {
        get { return _DefaultPage; }
        set { _DefaultPage = value; OpPropertyChanged(); DefaultPageChanged(value); }
    }

    private void DefaultPageChanged(string v)
    {
        // Service some...
    }
}
和二传手

您可以在 textBox 值更改时获取值。

 class ViewModel { private string _defaultPage; public string DefaultPage { get { return _DefaultPage; } set { _DefaultPage = value; OpPropertyChanged(); DefaultPageChanged(value); } } private void DefaultPageChanged(string v) { // Service some... } }

TextBox 绑定的默认行为是在 TextBox 失去焦点后更新绑定,这就是为什么您的绑定属性仅在用户键入之后更改,然后执行任何操作以失去对 TextBox 的焦点。 您显然不能使用 TextChanged 事件,因为它会在每次击键时触发。

保留您的 MVVM 并依赖边界属性首先更改的最佳方法是完全摆脱您的 EventTrigger 和您的 ICommand ,并简单地利用 DefaultPage 设置器被调用的时间。

在您的 SettingsViewModel 中:

private readonly IDefaultPageService _defaultPageService;
private string _defaultPage;

public string DefaultPage
{
    get { return _defaultPage; }
    set { Set(ref _defaultPage , value); OnSetDefaultPage(_defaultPage); }
}

private void OnSetDefaultPage(string defaultPage)
{
    _defaultPageService.SetDefaultPage(defaultPage);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM