I am looking for the correct syntax in my XAML to set a property in my Viewmodel (eg "BusyEditing"), which then has already been linked to the "IsEnabled" Binding of a button. Basically, I want the "Save" button to be enabled as soon as I enter a field to begin editing it. What would be even cooler is if the property was updated on the CHANGE of the开发者_如何学编程 textbox value, and not just the GotFocus.
Thanks in advance.
You can easily accomplish this using Commanding. If you bind a command on your ViewModel to your button, and the CanExecute method looks for valid info from your other inputs, then it will stay disabled until that condition is met.
In MVVM Light it would look something like this
public RelayCommand LogonCommand { get; private set; }
LogonCommand = new RelayCommand(
Logon,
CanLogon
);
private Boolean CanLogon(){
return !String.IsNullOrWhiteSpance(SomeProperty);
}
In your XAML just be sure to bind the button command to the ViewModel command:
<Button Command="{Binding LogonCommand}" />
If your textbox is bound to SomeProperty
this will work without any extra work, and no code behind necessary.
Also, if you want to have this trigger on property change instead of LostFocus, then you need to define that explicitly.
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource myDataSource}" Path="SomeProperty"
UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
The easiest way to do this is in the codebehind, although this is a bit of a foux pas with WPF developers, it is view logic and will not destroy unit testing possibilities.
<TextBox GotFocus="GotFocus"/>
<Button Name="SaveButton" Command="{Binding SaveCommand}" IsEnabled="False">
<TextBlock Text="Save"/>
</Button>
then
private void GotFocus( object sender, RoutedEventArgs e )
{
SaveButton.IsEnabled = true;
}
alternatively you could attach a command to the GotFocus event (http://stackoverflow.com/questions/1048517/wpf-calling-commands-via-events) setting a boolean on the viewmodel which is also queried in the "SaveCommand" CanExecute method.
It sounds like you want to name your property IsDirty, and only make the Save button available if the model has become dirty. You could have a CanSave property on your view model which checks the new model value against the original value when the model was loaded, e.g:
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);
}
}
Textboxes by default only update their bound property on lost focus, so you will need to set the UpdateSourceTrigger property on your text box:
<TextBox Text="{Binding ModelPropertyValue, UpdateSourceTrigger=PropertyChanged}" />
<Button IsEnabled="{Binding CanSave}">Save</Button>
You will need to use an EventTrigger
. Actually, two of them. One for GotFocus
and other for LostFocus
event.
Here is an example:
Using EventTrigger in XAML for MVVM – No Code Behind Code
Look for SetProperty
trigger action. That will be useful for you.
Lazy, quick and not so elegant solution if you only have one textbox:
<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>
The button will be enabled as soon as there is text in the textbox.
精彩评论