Reputation: 3583
I would like to show 'additional details' Textbox when the previous TextBox
's value is not 0.00 (zero). This is easily accomplished with DataTriggers:
<TextBox Name="FirstTB" Text="{Binding Amount, StringFormat=F2}"/><!--when this TB is not 0-->
<TextBox Name="SecondTB"> <!--show this TB-->
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Amount}" Value="0">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<TextBox Name="ThirdTB"/>
The issue is, however, when changing value of FirstTB
to <> 0 and pressing Tab
the focus jumps to the ThirdTB instead of SecondTB (even though SecondTB
now is Visible due to the DataTrigger). How can I fix this issue?
Sadly, UpdateSourceTrigger=PropertyChanged
does not appear to be an option due to its interference with StringFormat
s - it gives terrible UX when you are editing the value, carret jumps around like crazy due to constant StringFormat evaluation. Viewmodel used in example above:
public class MyVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private double _amount;
public double Amount
{
get { return _amount; }
set
{
_amount = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Amount)));
}
}
}
Upvotes: 0
Views: 49
Reputation: 5025
If you use an IValueConverter
you get a very elegant way for your problem. Everytime the value is changed, the logic is called.
public class IsZeroToHiddenConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double d && d == 0)
return Visibility.Hidden;
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You calso play around and add ConverterParameter
to decide if you want Collapsed
or Hidden
behavior.
<Grid>
<Grid.Resources>
<local:IsZeroToHiddenConverter x:Key="IsZeroToHiddenConverter"/>
</Grid.Resources>
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox x:Name="Tb1" Grid.Row="0" Width="100" Margin="5" Text="{Binding Path=Amount, StringFormat=F2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="Tb2" Grid.Row="1" Width="100" Margin="5" Visibility="{Binding Path=Amount, Converter={StaticResource IsZeroToHiddenConverter}}"/>
<TextBox x:Name="Tb3" Grid.Row="2" Width="100" Margin="5"/>
</Grid>
</Grid>
Upvotes: 0
Reputation: 2875
Maybe a stupid work around. But this will do the work:
View:
<TextBox Name="SecondTB" IsVisibleChanged="SecondTB_OnIsVisibleChanged">
<!--show this TB-->
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Amount, Mode=OneWay}" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
C#:
private void SecondTB_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (((bool) e.NewValue))
{
if(!(sender is TextBox txbx)) return;
ThirdTB.GotFocus += ThirdTbOnGotFocus;
}
}
private void ThirdTbOnGotFocus(object sender, RoutedEventArgs e)
{
SecondTB.Focus();
ThirdTB.GotFocus -= ThirdTbOnGotFocus;
}
Upvotes: 1