c# - 如何仅将 SelectionChanged 事件绑定到 XAML 中其他元素上的可见性属性
问题描述
给定的是 SelectionChanged 后的 ComboBox 应该成为可见的 TextBlock。我使用 ViemModel 构建此功能。
看法:
<ComboBox SelectionChanged="{mvvmHelper:EventBinding OnSelectionChanged}" />
<TextBlock Visibility="{Binding LanguageChanged, Converter={StaticResource BooleanVisibilityConverter}}"/>
视图模型:
bool LanguageChanged = false;
void OnSelectionChanged() => LanguageChanged = true;
我正在寻找仅在 XAML 中完成的优雅解决方案
到目前为止我尝试了什么:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsDropDownOpen, ElementName=Box, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
我想我必须使用故事板
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<EventTrigger RoutedEvent="SelectionChanged">
<BeginStoryboard>
<Storyboard>
???
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
另一个选项是 System.Windows.Interactivity 但这在 WpfCore 3.1 中不可用
解决方案
你有几个不错的选择。
由于最后一个使用 a 的解决方案DataTrigger
是最灵活的,因为它允许触发 的某些状态ComboBox.SelectedItem
,我建议实施它来解决您的问题。它也是一个仅限 XAML 的解决方案,不需要像LanguageChanged
.
为触发器属性设置动画
为了像 一样为属性设置动画LanguageChanged
,该属性必须是 a DependencyProperty
。因此,第一个示例实现LanguageChanged
为DependencyProperty
of MainWindow
:
主窗口.xaml.cs
partial class MainWindow : Window
{
public static readonly DependencyProperty LanguageChangedProperty = DependencyProperty.Register(
"LanguageChanged",
typeof(bool),
typeof(MainWindow),
new PropertyMetadata(default(bool)));
public bool LanguageChanged
{
get => (bool) GetValue(MainWindow.LanguageChangedProperty);
set => SetValue(MainWindow.LanguageChangedProperty, value);
}
}
主窗口.xaml
<Window x:Name="Window">
<StackPanel>
<TextBlock Text="Invisible"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=LanguageChanged, Converter={StaticResource BooleanToVisibilityConverter}}" />
<ComboBox>
<ComboBox.Triggers>
<EventTrigger RoutedEvent="ComboBox.SelectionChanged">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Window"
Storyboard.TargetProperty="LanguageChanged">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ComboBox.Triggers>
</ComboBox>
</StackPanel>
</Window>
直接为目标控件设置动画
如果您希望切换其可见性的控件与触发控件在同一范围内,您可以Visibility
直接设置动画:
主窗口.xaml
<Window x:Name="Window">
<StackPanel>
<TextBlock x:Name="InvisibleTextBlock"
Text="Invisible"
Visibility="Hidden" />
<ComboBox>
<ComboBox.Triggers>
<EventTrigger RoutedEvent="ComboBox.SelectionChanged">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InvisibleTextBlock"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ComboBox.Triggers>
</ComboBox>
</StackPanel>
</Window>
实现 IValueConverter
如果您希望向触发器添加更多条件,例如选择了哪个值,您应该绑定TextBlock.Visibility
toComboBox.SelectedItem
并使用 aIValueConverter
来决定是返回Visibility.Visible
还是Visibilty.Hidden
基于当前选定的项目:
主窗口.xaml
<Window x:Name="Window">
<Window.Resources>
<!-- TODO::Implement IValueConverter -->
<SelectedItemToVisibilityConverter x:Key="SelectedItemToVisibilityConverter" />
</Window.Resources>
<StackPanel>
<TextBlock Text="Invisible"
Visibility="{Binding ElementName=LanguageSelector, Path=SelectedItem, Converter={StaticResource SelectedItemToVisibilityConverter}}" />
<ComboBox x:Name="LanguageSelector" />
</StackPanel>
</Window>
在 TextBlock 上实现 DataTrigger
如果您希望向触发器添加更多条件,例如选择了哪个值,您还DataTrigger
可以TetxtBlock
在ComboBox.SelectedItem
. 然后,您必须将SelectedItem
转换为底层ComboBox
项目的实际类型,以便在绑定路径中引用项目的属性。
以下示例将 转换SelectedItem
为虚构类型LanguageItem
以访问LanguageItem.LanguageName
属性,以触发特定的选定语言:
主窗口.xaml
<Window x:Name="Window">
<StackPanel>
<TextBlock x:Name="InvisibleTextBlock" Text="Invisible">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=LanguageSelector, Path=SelectedItem.(LanguageItem.LanguageName)}"
Value="English">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ComboBox x:Name="LanguageSelector" />
</StackPanel>
</Window>
推荐阅读
- nginx - 为什么 Nginx 将我的子域重定向到域根目录?
- google-apps-script - 如何在谷歌脚本中构建这种类型的 UI?
- android - 有什么方法可以知道用户的 InApp 和订阅购买是否已经在全新的应用安装时恢复?
- reactjs - 使用 jest 测试 formik onSubmit 函数不起作用
- c# - 如何使用 topshelf 将 asp.net core 2.1 MVC 应用程序部署为 Windows 服务
- c++ - Cgo 找不到像这样的标准库
- java - 如何获得两个 jsonArrays 之间的差异?
- javascript - 如何通过 Javascript/AJAX 从 JSP 中的 HTML-Form 发送数据到 Java-Servlet?
- php - 如何使用 jinja2 在 /etc/bind 文件中增加 Serial
- javascript - 计算页面上断开链接的数量