我希望能够通过在 ViewModel 中设置属性来禁用用户的组合框。 最后,在某些情况下,用户应该只能查看 SelectedItem。
Stackoverflow 上有一些类似的问题,但没有一个能让我找到这个问题的解决方案。到目前为止,我通过窗口中的工具箱放置了一个组合框,并通过选择选项编辑模板的副本
开始编辑整个组合框模板的副本<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsCombboxEnabled}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding IsCombboxEnabled}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
IsEnabled
,禁用整个组合框,但我希望能够使用f.e.禁用下拉列表时文本块的编辑属性IsChecked
样式中的属性触发器不会改变任何内容这更接近解决方案:直接在 ToggleButton 中编辑 IsChecked 用法:
<ToggleButton x:Name="toggleButton"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
IsChecked="{Binding IsCombboxEnabled}"
Style="{StaticResource ComboBoxToggleButton}"/>
我想这已经让我成功了一半。现在根本无法打开 PopUp。 我现在正在努力在属性和数据上设置一种 MultiDataTrigger 绑定,以组合
IsChecked="{Binding IsCombboxEnabled}"
和替换的行 IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}"
如何正确组合这两个语句?或者有没有更干净、优雅的方式来实现这一点?
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2">
<Window.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF0F0F0" Offset="0.0"/>
<GradientStop Color="#FFE5E5E5" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FFACACAC"/>
<SolidColorBrush x:Key="ComboBox.Static.Glyph" Color="#FF606060"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Border" Color="#FFABADB3"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Border" Color="Transparent"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFECF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Glyph" Color="#FF000000"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Border" Color="#FF7EB4EA"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFEBF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Button.Border" Color="#FF7EB4EA"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAECFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Glyph" Color="#FF000000"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Border" Color="#FF569DE5"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAEBFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Button.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Background" Color="#FFF0F0F0"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Border" Color="#FFD9D9D9"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Glyph" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Border" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Border" Color="Transparent"/>
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="IsChecked" Value="{Binding IsToggleButtonEnabled}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot"
Background="{StaticResource ComboBox.Static.Background}"
BorderBrush="{StaticResource ComboBox.Static.Border}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Border x:Name="splitBorder" BorderBrush="Transparent"
BorderThickness="1"
HorizontalAlignment="Right"
Margin="0"
SnapsToDevicePixels="true"
Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="arrow" Data="F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z" Fill="{StaticResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.MouseOver.Glyph}"/>
</Trigger>
<!--<DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="True">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="False">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>-->
<DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="True">
<Setter Property="IsChecked" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding IsToggleButtonEnabled}" Value="False">
<Setter Property="IsChecked" Value="False" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Border}"/>
</MultiDataTrigger>
<!--<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True" />
<Condition Property="{Binding RelativeSource={RelativeSource Mode=Self},Path=IsToggleButtonEnabled}" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="IsChecked" Value="True" />
</MultiTrigger.Setters>
</MultiTrigger>-->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Pressed.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Disabled.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Border}"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Margin="1" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
<theme:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="dropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</theme:SystemDropShadowChrome>
</Popup>
<ToggleButton x:Name="toggleButton"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Style="{StaticResource ComboBoxToggleButton}"/>
<ContentPresenter x:Name="contentPresenter" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
IsHitTestVisible="false" Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
<Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="shadow" Value="#71000000"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect"
Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect"
Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="CmbboxToggleButtonTemplate" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
</Style>
</Window.Resources>
<Window.DataContext>
<local:ViewModel></local:ViewModel>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ComboBox Style="{DynamicResource CmbboxToggleButtonTemplate}"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200">
</ComboBox>
<Button Content="On/Off" Margin="50" Command="{Binding SwitchCommand}"></Button>
<TextBlock Grid.Row="1 " Grid.Column="0" Text="{Binding State}"></TextBlock>
</Grid>
</Window>
public class ViewModel : INotifyPropertyChanged
{
private string state;
private List<string> items;
private string selectedItem;
private bool isToggleButtonEnabled;
private Visibility visibilityCombobox;
public ViewModel()
{
Items = new List<string> { "item1", "item2", "item3" };
State = "On";
}
public List<string> Items
{
get => items;
set
{
items = value;
OnPropertyChanged();
}
}
public ICommand SwitchCommand => new RelayCommand(() =>
{
VisibilityCombobox = visibilityCombobox == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
});
public bool IsToggleButtonEnabled
{
get => isToggleButtonEnabled;
set
{
isToggleButtonEnabled = value;
OnPropertyChanged();
}
}
public Visibility VisibilityCombobox
{
get => visibilityCombobox;
set
{
visibilityCombobox = value;
State = value == Visibility.Visible ? "On" : "Off";
OnPropertyChanged();
}
}
public string SelectedItem
{
get => selectedItem;
set
{
selectedItem = value;
OnPropertyChanged();
}
}
public string State
{
get => state;
set
{
state = value;
OnPropertyChanged();
}}}
我认为您可以大大简化您的方法,并且仍然可以实现我认为您正在寻找的目标。
我希望能够通过在 ViewModel 中设置属性来禁用用户的组合框。最后,在某些情况下,用户应该只能查看 SelectedItem。
您的问题并不完全清楚,但我认为您想在禁用
ComboBox
时隐藏文本。这也可以理解为您希望它在禁用时看起来像 TextBlock
,所以我将提供这两个答案。
您可以使用
ViewModel
类来控制 ComboBox.Text
属性的状态依赖性,该属性控制显示的内容。通过这样做,您无需担心完全覆盖 ComboBox
模板。
public bool IsToggleButtonEnabled
{
get => isToggleButtonEnabled;
set
{
isToggleButtonEnabled = value;
OnPropertyChanged();
// also notify that the dependent properties changed
OnPropertyChanged(nameof(DisplayText));
OnPropertyChanged(nameof(State));
}
}
public string DisplayText
{
get => IsToggleButtonEnabled ? selectedItem : string.Empty;
}
<ToggleButton IsChecked="{Binding IsToggleButtonEnabled}"
Content="{Binding State}" />
<ComboBox Grid.Column="1"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
IsEnabled="{Binding IsToggleButtonEnabled}"
Text="{Binding DisplayText, Mode=OneWay}"/>
结果:
TextBlock
如果您的目标是使 ComboBox 在禁用时看起来像 TextBlock,则可以简单地根据状态交换控件。
public bool IsToggleButtonEnabled
{
get => isToggleButtonEnabled;
set
{
isToggleButtonEnabled = value;
OnPropertyChanged();
// also notify that the dependent properties changed
OnPropertyChanged(nameof(ComboBoxVisibility));
OnPropertyChanged(nameof(TextBlockVisibility));
}
}
public Visibility ComboBoxVisibility => IsToggleButtonEnabled ? Visibility.Visible : Visibility.Collapsed;
public Visibility TextBlockVisibility => IsToggleButtonEnabled ? Visibility.Hidden : Visibility.Visible;
<ToggleButton IsChecked="{Binding IsToggleButtonEnabled}"
Content="{Binding State}"
Grid.Row="1"/>
<ComboBox Grid.Column="1"
Grid.Row="1"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
IsEnabled="{Binding IsToggleButtonEnabled}"
Text="{Binding DisplayText, Mode=OneWay}"
Visibility="{Binding ComboBoxVisibility}"/>
<TextBlock Grid.Column="1"
Grid.Row="1"
Padding="6,3"
Text="{Binding SelectedItem}"
Visibility="{Binding TextBlockVisibility}"/>
您可以在此处查看生成这两个 gif 的完整代码:
您可以处理
ComboBox.DropDownOpened
事件并强制关闭下拉菜单:
MainWindow.xaml
<ComboBox DropDownOpened="ComboBox_DropDownOpened" />
MainWindow.xaml.cs
private void ComboBox_DropDownOpened(object sender, EventArgs e)
{
var comboBox = (ComboBox)sender;
bool canDropDownOpen = // TODO::Calculate value e.g. based on other values
if (!canDropDownOpen)
{
comboBox.IsDropDownOpen = false;
}
}
或延长
ComboBox
(推荐):
MainWindow.xaml
<ExtendedComboBox CanDropDownOpen="{Binding SomeProperty}" />
扩展组合框.cs
public class ExtendedComboBox : ComboBox
{
public bool CanDropDownOpen
{
get => (bool)GetValue(CanDropDownOpenProperty);
set => SetValue(CanDropDownOpenProperty, value);
}
public static readonly DependencyProperty CanDropDownOpenProperty = DependencyProperty.Register(
"CanDropDownOpen",
typeof(bool),
typeof(ExtendedComboBox),
new PropertyMetadata(true));
static ExtendedComboBox()
=> IsDropDownOpenProperty.OverrideMetadata(typeof(ExtendedComboBox), new FrameworkPropertyMetadata(default(bool), null, OnCoerceIsDropDownOpenValue));
// Reject any value and overwrite it with 'false' if CanDropDownOpen is 'false'
private static object OnCoerceIsDropDownOpenValue(DependencyObject d, object baseValue)
{
var extendedComboBox = (ExtendedComboBox)d;
return extendedComboBox.CanDropDownOpen
? baseValue
: false;
}
}