I have a button control in a WPF application which is used for log-in purposes. The button is dual purpose: when logged-out, it shall display the text "log in". When logged-in, it shall display the text "log out".
I could do this with databinding to an appropriate string property in the viewmodel. But it would be neater if I could simply databind to the "loggedIn" boolean (false for logged-out, true for logged-in) and then make the decision about what text to display on the button from within the view.
Is this possible?
You can achieve it using Style
in Xaml
without writing specific C# code.
Suppose you have IsLoggedIn
property in ViewModel
which is being changed on button bind command's execute method :
private void MyButtonCommandExecuteMethod()
{
this.IsLoggedIn = !this.IsLoggedIn;
}
private bool isLoggedIn;
public bool IsLoggedIn
{
get
{
return this.isLoggedIn;
}
set
{
this.isLoggedIn = value;
OnPropertyChanged(nameof(IsLoggedIn));
}
}
In the above code OnPropertyChanged
is method implementation of INotifyPropertyChanged
's PropertyChanged
event. If you using any framework or defined own name, then replace it with appropriate name.
You could define a style such as:
<Button Command="{Binding YourButtonCommand}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content" Value="Log In" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoggedIn}" Value="True">
<Setter Property="Content" Value="Log out" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
In the above code IsLoggedIn
is bind to DataTrigger
to update the Button
's Content
property based on it's value.
Another point, the button style is inherited from default style. If you any Keyed style then use it in BasedOn
Property.
Solution
Yes that is possible using value converter, specifically IValueConverter
. You can bind a bool
property, say BoolProperty
from your viewmodel
to button
using converter like this.
<Button Content="{Binding BoolProperty, Converter={StaticResource BoolConverter}}" />
Step 1: You need to create a converter that will accept bool value and return whatever string as you wish.
public class BoolConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
{
return value.ToString();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Step 2: Declare this converter as a resource in XAML (you will need to define local
namespace alias that contains the converter in your <Window ..>
start element.
<local:BoolConverter x:Key="BoolConverter" />
So now whenever property changed event is raised for BoolProperty
, this converter will be triggered and button
text will change appropriately.
Suggestion:
I am not sure why you think maintaining extra string
property is not a clean way. It is clean and is much simpler approach than using converter. Whatever I have shown is unnecessary overhead for your case, IMO. However, since you asked about possibility, I detailed it. Choice is yours! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With