Search code examples
wpfxamltriggersmultibindingupdatesourcetrigger

Using MultiBinding to bind elements


I have a login form that contains a username textbox and a password box.

I want the ok button to be enabled only when both the fields contain a value.

I have a converter that check for all the strings if they're null or empty.

I placed a breakpoint on the first line of the Convert method, and it stops only when the MenuItem initializes, afterwords, i.e. when I change the text it doesn't.

The following example works good, the problem is that the multibinding is not triggered when i change the text; it's only bound when initializing the form:

<!--The following is placed in the OK button-->
<Button.IsEnabled>
    <MultiBinding Converter="{StaticResource TrueForAllConverter}">
        <Binding ElementName="tbUserName" Path="Text"/>
        <Binding ElementName="tbPassword" Path="Password"/>
    </MultiBinding>
</Button.IsEnabled>

I think the issue is that you don't get notified when the remote binding source is changed (e.g. there is no an option to set UpdateTargetTrigger="PropertyChanged".

Any ideas?


Solution

  • I would suggest you look into command binding. A command can enable or disable your Login button automatically depending on some condition (ie. user name and password is not empty).

    public static RoutedCommand LoginCommand = new RoutedCommand();
    
    private void CanLoginExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = !string.IsNullOrEmpty(_userInfo.UserName) && !string.IsNullOrEmpty(_userInfo.Password);
        e.Handled = true;
    }
    
    private void LoginExecute(object sender, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("Loging in...");
        // Do you login here.
        e.Handled = true;
    }
    

    XAML command binding will look something like this

    <TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}" />
    <Button Command="local:LoginWindow.LoginCommand" >Login</Button>
    

    To register the command in XAML

    <Window.CommandBindings>
        <CommandBinding Command="local:LoginWindow.LoginCommand" CanExecute="CanLoginExecute" Executed="LoginExecute" />
    </Window.CommandBindings>
    

    Or in code behind

    public LoginWindow()
    {
        InitializeComponent();
    
        CommandBinding cb = new CommandBinding(LoginCommand, CanLoginExecute, LoginExecute);
        this.CommandBindings.Add(cb);
    }
    

    More readigin here.