c# - WPF ComboBox 禁用的项目仍然可以在边框上选择
问题描述
当我禁用某些组合框项目时,它们在嵌套文本块的左右边界上保持可选状态。
我尝试将文本框的边距和组合框项的填充设置为 0,然后我尝试将文本框和组合框项的 HorizontalAlignment 属性设置为“Stretch”,但没有结果。
WPF:
<Window.Resources>
<local:ComboboxItemsDisableConverter x:Key="ComboboxItemsDisableConverter"/>
</Window.Resources>
<ComboBox x:Name="comboBox" HorizontalAlignment="Right" Margin="0,13,10,0" Width="441"
SelectedIndex="{Binding ViewModel.SelectedNic, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"
ItemsSource="{Binding ViewModel.NICs, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"
SelectionChanged="ComboBox_SelectionChanged"
IsReadOnly="True" Height="25" VerticalAlignment="Top" Grid.Row="2">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem IsEnabled="{Binding OperationalStatus, Converter={StaticResource ComboboxItemsDisableConverter}}" >
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Description}" />
</ComboBoxItem>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
ComboBoxItemsDisableConverter 类:
class ComboboxItemsDisableConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (value == null) return value;
var Status = (OperationalStatus)value;
if (Status != OperationalStatus.Up)
return true;
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
我能做些什么来完全防止选择禁用的项目?
隐藏项目适用于以下代码:
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=OperationalStatus, Converter={StaticResource ComboboxItemsDisableConverter}}" Value="true">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
如果我使用这个标记
<ComboBox x:Name="comboBox" HorizontalAlignment="Right" Margin="0,13,10,0" Width="441" SelectedIndex="{Binding SelectedNic}" ItemsSource="{Binding NICs}" SelectionChanged="ComboBox_SelectionChanged" IsReadOnly="True" Height="25" VerticalAlignment="Top" Grid.Row="1">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding Description}" IsEnabled="{Binding OperationalStatus, Converter={StaticResource ComboboxItemsDisableConverter}}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
没有禁用任何项目
解决方案
您试图禁用项目容器内容,而不是项目容器。
您必须了解ItemsControl
它的ItemsSource
. 通常这些项目是数据模型。这些模型然后被包装到一个容器中。数据模型通常不是 type FrameworkElement
,它们是普通数据类型。为了呈现元素,它们必须是 type FrameworkElement
,这就是模型被包装到容器中的原因,例如ComboBoxItem
. 您可以通过定义一个ItemTemplate
.
您不与数据模型(容器内容)交互,而是与项目容器交互。当您只禁用内容时,您仍然可以与容器交互。该项目本身已Padding
应用。因此仍有足够的区域允许交互。
要解决您的问题,您必须禁用容器。为此,您必须在ItemContainerStyle
. 请注意,DataContext
这Style
是数据模型( 中的项目ItemsSource
):
<ComboBox>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled"
Value="{Binding OperationalStatus, Converter={StaticResource ComboboxItemsDisableConverter}}" />
</Style>
</ComboBox.ItemContainerStyle>
<!-- Remove the IsEnabled binding! -->
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Stretch"
Text="{Binding Description}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
请注意,从用户的角度来看,建议使用过滤从源集合中删除禁用的项目。不要显示占用空间且不允许交互的内容。这可能会让人很困惑,特别是如果用户不理解项目被禁用的原因以及他如何启用它们以选择它们时。
视图模型.cs
class ViewModel
{
public ObservableCollection<MyModel> NICs { get; }
public ViewModel()
{
this.NICs = new ObservableCollection<MyModel>();
// Only show items where OperationalStatus == OperationalStatus.Up
CollectionViewSource.GetDefaultView(this.NICs).Filter =
item => (item as MyModel).OperationalStatus == OperationalStatus.Up;
}
}
主窗口.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<ComboBox ItemsSource="{Binding NICs}" />
</Window>
推荐阅读
- java - 如何在Java中将黑白.png图像着色为某种颜色
- jquery - .append 一个带有图片的新 div
- python - 熊猫应用多列作为输入
- php - PHP - Mysqli 每月考勤日历
- javascript - 为客户端逻辑运行 js 客户端
- stm32 - Nucleo 板上的 STM-Link 未枚举
- python - 使用 asyncio 和 contextvars 在 python 中的两个异步程序之间共享状态
- entity-framework-core - “Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.SqlServerOptionsExtension”类型中的方法“get_Info”
- android - 处理程序示例由于某种原因无法正常工作
- python - 在 doctest 的文档字符串的行前添加“>>>”的任何快捷方式?