【问题标题】:MVVM - WPF: Updating view model boolean property when TextBox is being editedMVVM - WPF:在编辑文本框时更新视图模型布尔属性
【发布时间】:2013-12-30 21:49:07
【问题描述】:

我找到了一些关于如何从视图模型中选择控件的示例,但一定不能在正确的术语上搜索如何让它以相反的方式工作。基本上我只想在我的视图模型中更新一个布尔值,当一个文本框正在被编辑时,当它没有被编辑时。我认为这与想知道它何时获得和失去焦点是一样的。

所以我创建了一个 FocusExtension 类,如下所述:Set focus on textbox in WPF from view model (C#)

但它不会触发我的视图模型属性“EditingMyTargetField”的访问器,并在我的 XAML 中使用以下行:

my:FocusExtension.IsFocused="{Binding EditingMyTargetField}"

【问题讨论】:

  • 一般来说,ViewModel 不应该真正关心值是否在更改(在 UI 中),而只是在它更改时才关心。如果您仅出于 UI 原因设置标志,则可以使用代码隐藏或 UI 中的触发器。
  • 原因是因为我想在编辑文本框时启用特定按钮,并在不编辑时禁用它。我将 IsEnabled 属性绑定到与该按钮有关的命令的 CanExecute 方法。 CanExecute 方法引用了我的 ViewModel 中的一个属性,该属性还需要与是否正在编辑文本框相关联。对于另一个文本框,如果在构成表单的最后一个文本框上被选中,我需要让我的一个命令以一种方式运行,如果不是,则以不同的方式运行。 (我不控制应用要求)。
  • 要记住的一点是,这种行为可能是您想要进行单元测试的行为,在这种情况下,绝对可以使用代码隐藏或触发器。

标签: wpf mvvm


【解决方案1】:

我会探索除最佳答案之外的其他答案,因为其他人已经改进了批准的解决方案。我用一个文本框测试了 Zamotic 的 FocusExtension,它成功地触发了与视图模型的绑定。他的解决方案具有在元素获得或失去焦点时触发的事件,然后将 dependencyproperty 值设置为正确的状态。我还必须在标记中明确将绑定模式声明为 TwoWay,但如果需要,您可以更改扩展名以默认设置双向绑定。

<TextBox local:FocusExtension.IsFocused="{Binding TextIsFocused, Mode=TwoWay}"/>

【讨论】:

  • 我认为 TwoWay 选项可能是它,但看起来我的问题是在创建控件时永远不会触发或调用 FocusExtension 方法。也许在 C# 到 vb.net 的转换中丢失了一些东西。
  • 好的,我使用了上面问题中链接中的 Zamotic 实现,而不是投票最多的那个,它开始工作了。
【解决方案2】:

在完成您的确切要求后,我修改了答案。

在这种情况下,当您想要在鼠标isOver 文本框和NOT 时启用按钮时,您只需要使用 2 个事件。

这两个事件是: MouseEnterMouseLeave

这些事件捕获光标在控件上和不在控件上的时刻。

您需要一个 bool 属性来绑定到您的 Button,以便根据条件*(鼠标悬停或不悬停)更改其启用*。

private bool _isBtnEnable = false;

        public bool IsBtnEnable
        {
            get { return _isBtnEnable; }
            set
            {
                _isBtnEnable = value;
                OnPropertyChanged("IsBtnEnable");
            }
        }

在 Xaml 中:

  <Grid>
        <StackPanel Orientation="Horizontal">
            <TextBox Width="100" Text="{Binding 
Txt,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
 Mouse.MouseEnter="TextBox_MouseEnter" 
 Mouse.MouseLeave="TextBox_MouseLeave"/>
                <Button Width="70" Name="btn" Content="Save" Margin="20,0,0,0" 
IsEnabled="{Binding IsBtnEnable,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged
/>

        </StackPanel>

    </Grid>

在 Xaml.cs 中:

private void TextBox_MouseEnter(object sender, MouseEventArgs e)
        {
            IsBtnEnable = true;
        }

        private void TextBox_MouseLeave(object sender, MouseEventArgs e)
        { 

   if (string.IsNullOrEmpty(Txt)) (Checking if the TextBox is empty,remove it 
if regardless of text you want to disable the button on cursor being not over the
 TextBox but how will you click Save then because it will get disabled when you moved your mouse)
            IsBtnEnable = false;
        }

我认为这会达到你想要的效果。 :)

【讨论】:

  • 在这种情况下,文本框中是否有文本无关紧要,因为如果光标存在于文本框中,无论它包含什么,我都需要启用或禁用该行为。
  • Kevin 的解决方案满足所有要求。我想避免代码落后。相对于文本框的鼠标行为并不重要。 UI 是否使文本框成为焦点或用户无关紧要。行为应该是相同的。只需绑定到控件的 IsFocused 属性即可完成所有这些事情。感谢您提出的解决方案。
猜你喜欢
  • 2013-03-10
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
相关资源
最近更新 更多