Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind WPF control text to boolean, and make decision about text in xaml

Tags:

c#

mvvm

wpf

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?

like image 757
Q'' Avatar asked Jan 29 '23 01:01

Q''


2 Answers

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.

like image 107
user1672994 Avatar answered Jan 30 '23 13:01

user1672994


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! :)

like image 44
Nikhil Vartak Avatar answered Jan 30 '23 13:01

Nikhil Vartak