WPF 组合框样式
WPF Combo Box Style
我有两个组合框:CarTypeComboBox 和 SeriesComboBox。
问题:
1. 我希望 SeriesCombox 仅在用户 select BMW 时 visible。
2. System.Windows.Style 出现在 SeriesComboBox 中。
谢谢
完整代码:
<Window x:Class="StyleTrigger.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:StyleTrigger"
xmlns:local2="clr-namespace:ComboBoxData"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources >
<local2:ComboBoxItemCollection x:Key="CarItemsCollection"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Grid.Column="0" >
<Label x:Name="CarBrand" Height="30" Width="75" Margin="10,0,0,0" Content="Car Brand"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="CarTypeComboBox" Margin="10,0,0,0" Width="100" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource CarItemsCollection}}"
DisplayMemberPath="CarType"
SelectedValuePath="CarID"
/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" >
<Label x:Name="CarSeries" Height="30" Width="75" Margin="10,0,0,0" Content="Car Series"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="SeriesComboBox" Margin="10,0,0,0" Width="100" Height="30"
HorizontalAlignment="Left" VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox>
</StackPanel>
</Grid>
</Window>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class SingleComboBoxItem
{
public SingleComboBoxItem(int pCarID,String pCarBrand)
{
CarID = pCarID;
CarType = pCarBrand;
}
public string CarType { get; set; }
public int CarID { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class ComboBoxItemCollection : ObservableCollection<SingleComboBoxItem>
{
public ComboBoxItemCollection() : base()
{
Add(new SingleComboBoxItem(1,"Honda"));
Add(new SingleComboBoxItem(2,"Toyota"));
Add(new SingleComboBoxItem(3,"BMW"));
Add(new SingleComboBoxItem(4,"Dodge"));
Add(new SingleComboBoxItem(5,"Lexus"));
}
}
}
将默认值 Hidden
添加到 Style
本身 ,而不是触发器。
您的 ComboBox 样式应如下所示:
<Style TargetType="ComboBox">
<!-- Just add this one Setter -->
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
不要在 ComboBox
标签本身上设置 Visibility
属性。 ComboBox
上没有 Visibility="Hidden"
。这将覆盖样式设置器并且它将 永远不会 可见。仅在样式的设置器中设置 Visibility
。
更新
既然我已经看过完整的代码,我可以提供更多的见解。首先,您说“当我 select BMW 时,SeriesComboBox 没有出现。”,但是您刚刚发布的版本中发生的事情是,当您 不要 select 宝马。现在,让我们来看看它做了什么:
该下拉列表中存在异常:最后一项是 System.Windows.Style
。我敢打赌,你从来没有在路上见过那种宝马车型。
您的 Style
定义正确,我认为它可能在我们开始为您争吵之前就已经正确了。问题是您没有将它分配给 ComboBox
的 Style
属性。相反,您将其添加到默认内容 属性,在 ComboBox
的情况下是 Items
。在 WPF 中,您可以在 ComboBox
(或 ListBox
)项集合中几乎比喻地抛出 任何东西 。这是 object
的集合。它会吃掉你喂给它的任何旧垃圾,而且从不抱怨。由于您没有为那个对象指定 DisplayMemberPath
,它只是高兴地依次对每个对象调用 ToString()
。
所以要将样式赋给ComboBox
的Style
属性,放在<ComboBox.Style>
:
里面
<ComboBox
x:Name="SeriesComboBox"
Margin="10,0,0,0"
Width="100"
Height="30"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger
Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}"
Value="BMW"
>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
您还可以在 Resources
中定义 Style
,给它 x:Key="SeriesComboBoxStyle"
,并在 ComboBox
标签上设置 Style
属性:Style="{StaticResource SeriesComboBoxStyle}"
.
我有两个组合框:CarTypeComboBox 和 SeriesComboBox。
问题: 1. 我希望 SeriesCombox 仅在用户 select BMW 时 visible。 2. System.Windows.Style 出现在 SeriesComboBox 中。
谢谢
完整代码:
<Window x:Class="StyleTrigger.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:StyleTrigger"
xmlns:local2="clr-namespace:ComboBoxData"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources >
<local2:ComboBoxItemCollection x:Key="CarItemsCollection"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" Grid.Column="0" >
<Label x:Name="CarBrand" Height="30" Width="75" Margin="10,0,0,0" Content="Car Brand"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="CarTypeComboBox" Margin="10,0,0,0" Width="100" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource CarItemsCollection}}"
DisplayMemberPath="CarType"
SelectedValuePath="CarID"
/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" >
<Label x:Name="CarSeries" Height="30" Width="75" Margin="10,0,0,0" Content="Car Series"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="SeriesComboBox" Margin="10,0,0,0" Width="100" Height="30"
HorizontalAlignment="Left" VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox>
</StackPanel>
</Grid>
</Window>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class SingleComboBoxItem
{
public SingleComboBoxItem(int pCarID,String pCarBrand)
{
CarID = pCarID;
CarType = pCarBrand;
}
public string CarType { get; set; }
public int CarID { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ComboBoxData
{
class ComboBoxItemCollection : ObservableCollection<SingleComboBoxItem>
{
public ComboBoxItemCollection() : base()
{
Add(new SingleComboBoxItem(1,"Honda"));
Add(new SingleComboBoxItem(2,"Toyota"));
Add(new SingleComboBoxItem(3,"BMW"));
Add(new SingleComboBoxItem(4,"Dodge"));
Add(new SingleComboBoxItem(5,"Lexus"));
}
}
}
将默认值 Hidden
添加到 Style
本身 ,而不是触发器。
您的 ComboBox 样式应如下所示:
<Style TargetType="ComboBox">
<!-- Just add this one Setter -->
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}" Value="BMW">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
不要在 ComboBox
标签本身上设置 Visibility
属性。 ComboBox
上没有 Visibility="Hidden"
。这将覆盖样式设置器并且它将 永远不会 可见。仅在样式的设置器中设置 Visibility
。
更新
既然我已经看过完整的代码,我可以提供更多的见解。首先,您说“当我 select BMW 时,SeriesComboBox 没有出现。”,但是您刚刚发布的版本中发生的事情是,当您 不要 select 宝马。现在,让我们来看看它做了什么:
该下拉列表中存在异常:最后一项是 System.Windows.Style
。我敢打赌,你从来没有在路上见过那种宝马车型。
您的 Style
定义正确,我认为它可能在我们开始为您争吵之前就已经正确了。问题是您没有将它分配给 ComboBox
的 Style
属性。相反,您将其添加到默认内容 属性,在 ComboBox
的情况下是 Items
。在 WPF 中,您可以在 ComboBox
(或 ListBox
)项集合中几乎比喻地抛出 任何东西 。这是 object
的集合。它会吃掉你喂给它的任何旧垃圾,而且从不抱怨。由于您没有为那个对象指定 DisplayMemberPath
,它只是高兴地依次对每个对象调用 ToString()
。
所以要将样式赋给ComboBox
的Style
属性,放在<ComboBox.Style>
:
<ComboBox
x:Name="SeriesComboBox"
Margin="10,0,0,0"
Width="100"
Height="30"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<sys:String>230</sys:String>
<sys:String>280</sys:String>
<sys:String>530</sys:String>
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger
Binding="{Binding SelectedItem.CarType, ElementName=CarTypeComboBox}"
Value="BMW"
>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
您还可以在 Resources
中定义 Style
,给它 x:Key="SeriesComboBoxStyle"
,并在 ComboBox
标签上设置 Style
属性:Style="{StaticResource SeriesComboBoxStyle}"
.