当控件获得焦点时,在ViewModel中更新属性

时间:2011-01-12 13:43:26

标签: c# wpf xaml mvvm

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

提前致谢。

5 个答案:

答案 0 :(得分:3)

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

MVVM Light中,它看起来像这样

public RelayCommand LogonCommand { get; private set; }

LogonCommand = new RelayCommand(
                    Logon,
                    CanLogon
                );

private Boolean CanLogon(){
    return !String.IsNullOrWhiteSpance(SomeProperty);
}

在XAML中,只需确保将button命令绑定到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>

答案 1 :(得分:0)

最简单的方法是在代码隐藏中,虽然这对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),在viewmodel上设置一个布尔值,该命令也在“SaveCommand”中查询“CanExecute方法。

答案 2 :(得分:0)

听起来您想要将您的属性命名为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>

答案 3 :(得分:0)

您需要使用EventTrigger。实际上,其中两个。一个用于GotFocus,另一个用于LostFocus事件。

以下是一个例子:

Using EventTrigger in XAML for MVVM – No Code Behind Code

查找SetProperty触发器操作。这对你有用。

答案 4 :(得分:0)

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

    <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>

只要文本框中有文字,该按钮就会启用。