I am having difficulty figuring out how to toggle the visibility between three buttons. Here is the scenario:
- I have 3 buttons on a user control, an
Edit
button, anOK
button, and aCancel
button. - The
Ok
andCancel
buttons are grouped together in a stack panel. - The
Edit
button is by itself. - I would like when the
Edit
button is pressed, that it (theEdit
button) is hidden and the stack panel containing theOk
andCancel
buttons are shown. - When either the
Cancel
orOk
buttons are pressed, they are hidden, and theEdit
button is shown again. - There will be 7 lines on this form that are all very similar, with a label, text box, and an edit button.
- Is it possible to use only a few methods to control the visibility of all of the buttons/ stack panels.
- i.e. Can I have one Edit method and show the stack panel depending on the text box control name/ binding, instead of having to right 7 methods for showing the stack panel, 7 Ok methods and 7 cancel methods?
Here is the line on the form with the Edit
button:
And here is the line on the form with the Ok
and Cancel
buttons:
Here is the XAML code that I've come up with for this line:
<StackPanel
Orientation="Horizontal"
HorizontalAlignment="Center"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="4">
<Label
Style="{StaticResource DeviceInfoPropertyLabelStyle}">
CONTROLLER NAME:
</Label>
<TextBox
Text="{Binding ControllerName}"
Style="{StaticResource DeviceInfoTextBoxStyle}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Orientation="Horizontal"
Grid.Column="0">
<Button
Command="{Binding EditCommand}"
Visibility="{Binding IsEditButtonVisible, Converter={StaticResource BoolToVisibilityConverter}, FallbackValue=Collapsed}"
Style="{StaticResource DeviceInfoEditButtonStyle}">
Edit
</Button>
</StackPanel>
<StackPanel
x:Name="EditControllerNameStackPanel"
Orientation="Horizontal"
Grid.Column="0"
Visibility="{Binding IsOkCancelButtonVisible, Converter={StaticResource BoolToVisibilityConverter}, FallbackValue=Visible}">
<Button
Command="{Binding OkEditCommand}"
Style="{StaticResource DeviceInfoEditOkButtonStyle}">
OK
</Button>
<Button
Command="{Binding CancelEditCommand}"
Style="{StaticResource DeviceInfoEditCancelButtonStyle}">
CANCEL
</Button>
</StackPanel>
</Grid>
</StackPanel>
Here is the code in the ViewModel that I have so far. It's only a skeleton at this point:
public bool IsEditButtonVisible
{
get
{
bool output = false;
if (true)
{
return true;
}
return output;
}
}
public bool IsOkCancelButtonVisible
{
get => true;
}
[RelayCommand]
private void Edit()
{
if (true)
{
}
}
[RelayCommand]
private void OkEdit()
{
}
[RelayCommand]
private void CancelEdit()
{
}
Note that I am using the MVVM Community Toolkit.
Let me know if I need to provide any additional information.
Thanks
CodePudding user response:
You can use just one boolean to toggle the visibility. Change BoolToVisibilityConverter code a bit..
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool b)
{
if (parameter is string str && str == "Inverse")
return b ? Visibility.Hidden : Visibility.Visible;
return b ? Visibility.Visible : Visibility.Hidden;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Edit button
<Button
Visibility="{Binding IsEditButtonVisible, Converter={StaticResource BoolToVisibilityConverter}}">
OK/Cancel stackpanel
<StackPanel
Visibility="{Binding IsEditButtonVisible, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=Inverse}">
ViewModel (sorry I don't use MVVM Community Toolkit)
public class ViewModel : INotifyPropertyChanged
{
private bool _isEditButtonVisible;
public bool IsEditButtonVisible
{
set
{
_isEditButtonVisible = value;
OnPropertyChanged(nameof(IsEditButtonVisible));
}
get => _isEditButtonVisible;
}
private void Edit()
{
IsEditButtonVisible = false;
}
private void Ok()
{
IsEditButtonVisible = true;
}
private void Cancel()
{
IsEditButtonVisible = true;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// other code
}
To apply the same logic over the other 7 similar groups, you must have at least 7 booleans, but you can have 3 commands only, where you can pass the name of the group to the command, and the command will toggle the appropriate group based on the passed parameter
In View
<Button
Command="{Binding OkCommand}"
CommandParameter="group1">
OK
</Button>
In ViewModel
private void Edit(string commandParameter)
{
IsEdit1ButtonVisible = commandParameter != "group1";
IsEdit2ButtonVisible = commandParameter != "group2";
IsEdit3ButtonVisible = commandParameter != "group3";
// etc...
}
private void Ok(string commandParameter)
{
IsEdit1ButtonVisible = commandParameter == "group1";
IsEdit2ButtonVisible = commandParameter == "group2";
IsEdit3ButtonVisible = commandParameter == "group3";
// etc...
}
private void Cancel(string commandParameter)
{
IsEdit1ButtonVisible = commandParameter == "group1";
IsEdit2ButtonVisible = commandParameter == "group2";
IsEdit3ButtonVisible = commandParameter == "group3";
// etc...
}