简体   繁体   中英

WPF - Two way binding

I've created user control (toggle button) that contains property called ButtonState (Checked, Disabled or Available). Control has built-in mouse click event which converts its state from available to pressed or from pressed to available (if it is disabled it can't be clicked).

My purpose is create "tree" of buttons, something like that:

OPTION 1                          OPTION 2
SUBOPTION1 SUBOPTION1             SUBOPTION1 SUBOPTION1
....                              .....

So if I click on button "OPTION 1" (it changes state to PRESSED within control) I would like to button "OPTION 2" go to state DISABLED. If I click on OPTION 1 again, it converts from PRESSED to AVAILABLE and OPTION2 goes to AVAILABLE TOO. The same procedure should be run if I click on OPTION2 (analogously of course). Briefly again: only one button can have PRESSED state and if one has such state other one must be disabled. And if one is available - the other must be available as well.

I've created converter (InverseButtonStateConverter) BUTTONSTATE -> BUTTONSTATE

public object Convert(object value, Type targetType, object parameter,       System.Globalization.CultureInfo culture)
{
switch (((Controls.ButtonState)value))
    {
            case Controls.ButtonState.Available: return Controls.ButtonState.Available;
            case Controls.ButtonState.Pressed: return Controls.ButtonState.Disable;
            case Controls.ButtonState.Disable: return Controls.ButtonState.Available;
            default: return Controls.ButtonState.Available;
    }
}

Using in XAML :

        <Controls:ToggleRectangleButton HorizontalAlignment="Center" VerticalAlignment="Center" Height="109" Width="210" ButtonText2="Bilety jednorazowe" TextFontSize="25" Grid.Column="0" x:Name="btSingleTicket" Click="btSingleTicket_Click" ButtonState="{Binding ElementName=btTimeTicket, Path=ButtonState, Converter={StaticResource InverseButtonStateConverter}}"/>
        <Controls:ToggleRectangleButton HorizontalAlignment="Center" VerticalAlignment="Center" Height="109" Width="210" ButtonText2="Bilety czasowe" TextFontSize="25" Grid.Column="3" x:Name="btTimeTicket" Click="btTimeTicket_Click" ButtonState="{Binding ElementName=btSingleTicket, Path=ButtonState, Converter={StaticResource InverseButtonStateConverter}}"/>

When I run this code it works good when I'm clicking on one button. If I interrupt it by clicking on second (it won't work as I would like to) first's button ability to correctyly working disappear.

I've tried to change binding modes but I have no idea how to make it. Some help?

Using two ToggleButton s, and a boolean inverter converter, you can achieve it by binding their respective IsEnabled properties to the IsChecked properties:

<ToggleButton Content="1" x:Name="btn1" IsEnabled="{Binding ElementName=btn2, Path=IsChecked, Converter={StaticResource BooleanInverterConverter}}"/>
<ToggleButton Content="2" x:Name="btn2" IsEnabled="{Binding ElementName=btn1, Path=IsChecked, Converter={StaticResource BooleanInverterConverter}}"/>

And the ValueConverter (simple implementation):

public class BooleanInverterConverter : IValueConverter 
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    {
        return !(bool) value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    {
        throw new NotImplementedException();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM