【问题标题】:Update property in ViewModel when a control Gets Focus当控件获得焦点时更新 ViewModel 中的属性
【发布时间】:2011-01-12 13:43:26
【问题描述】:

我正在我的 XAML 中寻找正确的语法来设置我的 Viewmodel 中的属性(例如“BusyEditing”),然后它已经链接到按钮的“IsEnabled”绑定。 基本上,我希望在输入字段开始编辑时启用“保存”按钮。更酷的是,如果属性是在文本框值的更改时更新的,而不仅仅是 GotFocus。

提前致谢。

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    您可以使用Commanding 轻松完成此操作。如果您将 ViewModel 上的命令绑定到您的按钮,并且 CanExecute 方法从您的其他输入中查找有效信息,那么它将保持禁用状态,直到满足该条件。

    MVVM Light 中看起来像这样

    public RelayCommand LogonCommand { get; private set; }
    
    LogonCommand = new RelayCommand(
                        Logon,
                        CanLogon
                    );
    
    private Boolean CanLogon(){
        return !String.IsNullOrWhiteSpance(SomeProperty);
    }
    

    在您的 XAML 中,只需确保将按钮命令绑定到 ViewModel 命令:

    <Button Command="{Binding LogonCommand}" />
    

    如果您的文本框绑定到 SomeProperty,则无需任何额外工作,也无需任何代码。

    此外,如果您想使用 trigger on property change 而不是 LostFocus,则需要明确定义。

    <TextBox>
      <TextBox.Text>
        <Binding Source="{StaticResource myDataSource}" Path="SomeProperty"
                 UpdateSourceTrigger="PropertyChanged"/>
      </TextBox.Text>
    </TextBox>
    

    【讨论】:

      【解决方案2】:

      执行此操作的最简单方法是在代码隐藏中,虽然这对 WPF 开发人员来说有点小题大做,但它是视图逻辑,不会破坏单元测试的可能性。

          <TextBox GotFocus="GotFocus"/>
          <Button Name="SaveButton" Command="{Binding SaveCommand}" IsEnabled="False">
              <TextBlock Text="Save"/>
          </Button>
      

      然后

          private void GotFocus( object sender, RoutedEventArgs e )
          {
              SaveButton.IsEnabled = true;
          }
      

      或者,您可以将命令附加到 GotFocus 事件 (http://stackoverflow.com/questions/1048517/wpf-calling-commands-via-events) 在视图模型上设置一个布尔值,该值也在“SaveCommand”中查询" CanExecute 方法。

      【讨论】:

        【解决方案3】:

        听起来您想将属性命名为 IsDirty,并且仅在模型变脏时才使“保存”按钮可用。您可以在视图模型上有一个 CanSave 属性,该属性在加载模型时检查新模型值与原始值,例如:

        public bool CanSave
        {
          get
          {
            return this.IsDirty;     
          }
        }
        
        public bool IsDirty
        {
          get
          {
            if (this.ModelPropertyValue != this.ModelOriginalPropertyValue)
            {
              return true;  
            }
        
            return false;
          }
        }
        
        private string modelPropertyValue;
        public string ModelPropertyValue
        {
          get
          {
            return this.modelPropertyValue;
          }
        
          set
          {
            if (this.modelPropertyValue == value) 
            {
              return;
            }
        
            this.modelPropertyValue = value;
            OnPropertyChanged(() => this.ModelPropertyValue);
            OnPropertyChanged(() => this.CanSave);
          }
        }
        

        默认情况下,文本框仅在失去焦点时更新其绑定属性,因此您需要在文本框上设置 UpdateSourceTrigger 属性:

        <TextBox Text="{Binding ModelPropertyValue, UpdateSourceTrigger=PropertyChanged}" />
        <Button IsEnabled="{Binding CanSave}">Save</Button>
        

        【讨论】:

          【解决方案4】:

          您需要使用EventTrigger。事实上,他们两个。一个用于GotFocus,另一个用于LostFocus 事件。

          这是一个例子:

          Using EventTrigger in XAML for MVVM – No Code Behind Code

          寻找SetProperty 触发动作。这对你很有用。

          【讨论】:

            【解决方案5】:

            如果您只有一个文本框,那么懒惰、快速且不那么优雅的解决方案:

                <TextBox Name="TB" Width="200"/>
                <Button Content="Save">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ElementName=TB, Path=Text}" Value="">
                                    <Setter Property="IsEnabled" Value="False"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>
            

            一旦文本框中有文本,按钮就会被启用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-08-24
              • 2013-11-26
              • 1970-01-01
              • 1970-01-01
              • 2019-06-26
              • 1970-01-01
              • 1970-01-01
              • 2013-03-22
              相关资源
              最近更新 更多