WPF桌面端开发1-常用组件之ComboBox

ComboBox

1
2
3
4
5
6
7
8
9
10
11
12
<ComboBox
x:Name="ip_cb"
Height="auto"
Margin="0,0,0,0"
Padding="10,0,0,0"
VerticalContentAlignment="Center"
Cursor="Hand"
DisplayMemberPath="Value"
FontSize="14"
SelectedValuePath="Key"
SelectionChanged="ip_cb_SelectionChanged"
Style="{StaticResource ComboBoxStyle}" />

数据绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var addressList = ZConfig.ipaddressList();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Key", typeof(string)));
dt.Columns.Add(new DataColumn("Value", typeof(string)));

for (int i = 0; i < addressList.Count; i++)
{
dt.Rows.Add(addressList[i], addressList[i]);
}

ip_cb.ItemsSource = dt.DefaultView;
if (addressList.Count > 0)
{
ip_cb.SelectedIndex = 0;
}

注意

ip_cb.SelectedIndex = 0;会触发回调。

选中回调

1
2
3
4
5
6
7
private void ip_cb_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (ip_cb.SelectedValue != null)
{
var localIP = ip_cb.SelectedValue.ToString();
}
}

获取到的是SelectedValuePath对应的值

1
2
3
4
//保存的ID
ZCommonData.classid = Convert.ToInt32(cmbClass.SelectedValue.ToString());
//显示的名称
ZCommonData.classname = cmbClass.Text;

绑定自定义对象

绑定ComboBox的显示文本和实际值,可以使用DisplayMemberPathSelectedValuePath属性来实现。

首先,假设你的数据模型类Item包含Name作为显示文本和Value作为实际值:

1
2
3
4
5
public class Item
{
public string Name { get; set; }
public int Value { get; set; }
}

然后,在XAML中,你需要指定DisplayMemberPath用于显示文本和SelectedValuePath用于实际值,并绑定SelectedValue属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Window x:Class="ComboBoxBinding.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:ComboBoxBinding"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ComboBox x:Name="comboBox"
DisplayMemberPath="Name"
SelectedValuePath="Value"
SelectedValue="{Binding SelectedItemId, Mode=TwoWay}">
</ComboBox>
</Grid>
</Window>

在C#中设置数据源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public partial class MainWindow : Window
{
public ObservableCollection<Item> Items { get; set; }

private int _selectedItemId;
public int SelectedItemId
{
get { return _selectedItemId; }
set
{
_selectedItemId = value;
// Do something when selected item changes
}
}

public MainWindow()
{
InitializeComponent();

Items = new ObservableCollection<Item>
{
new Item { Name = "Item 1", Value = 1 },
new Item { Name = "Item 2", Value = 2 },
new Item { Name = "Item 3", Value = 3 }
};

comboBox.ItemsSource = Items;
// Optionally, set the initial selected item
SelectedItemId = Items[0].Value;
}
}

在这个示例中,Items集合作为ComboBox的数据源,SelectedItemId用来绑定ComboBox选中项的实际值。

这样ComboBox就会显示Name属性作为每个选项的文本,并且可以通过SelectedValue获取选中项的实际值。

定义样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- ComBoBox项鼠标经过背景色 -->
<SolidColorBrush x:Key="ComboBoxMouseOverBackground" Color="#f0f0f0" />
<!-- Combox右侧下拉按钮 -->
<Style x:Key="ComboxStyleBtn" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- 下拉按钮内部背景色 -->
<Border
x:Name="Back"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="1"
CornerRadius="4">
<!-- 下拉按钮内边框 -->

<Image
Name="PathFill"
Height="12"
Margin="0,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Source="/Images/UserCenter/jiantou.png" />

</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Back" Property="Background" Value="Transparent" />
<Setter TargetName="Back" Property="BorderBrush" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Combox -->
<Style x:Key="ComboBoxStyle" TargetType="ComboBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<!-- 文字区域背景和边线样式 -->
<TextBox
Grid.Column="0"
Padding="10,0,0,0"
VerticalAlignment="Center"
Background="Transparent"
BorderBrush="#c0c0c0"
BorderThickness="0"
Foreground="Black"
IsReadOnly="{TemplateBinding IsReadOnly}"
Text="{TemplateBinding Text}" />

<!-- 右侧下拉button设置 -->
<Border BorderThickness="0">
<ToggleButton
BorderBrush="Black"
BorderThickness="3"
ClickMode="Press"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource ComboxStyleBtn}" />
</Border>
<!-- 弹出popup整体设置 -->
<Popup
x:Name="Popup"
AllowsTransparency="True"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid
x:Name="DropDown"
Width="{TemplateBinding ActualWidth}"
MaxHeight="200"
SnapsToDevicePixels="True">
<Border
x:Name="DropDownBorder"
BorderBrush="#e8e8e8"
BorderThickness="1,0,1,1" />
<ScrollViewer
Margin="1"
CanContentScroll="True"
HorizontalScrollBarVisibility="Disabled"
SnapsToDevicePixels="True"
VerticalScrollBarVisibility="Auto">
<!-- StackPanel 用于显示子级,方法是将 IsItemsHost 设置为 True -->
<StackPanel
Background="White"
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<!-- ComBoxItem -->
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="MinHeight" Value="32" />
<Setter Property="MinWidth" Value="60" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border
Name="_back"
Background="Transparent"
BorderBrush="#f3f3f3"
BorderThickness="0"
CornerRadius="4">
<ContentPresenter Margin="10,0,10,0" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="_back" Property="Background" Value="{StaticResource ComboBoxMouseOverBackground}" />
</Trigger>
<!-- 下拉框背景色 -->
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="_back" Property="Background" Value="{StaticResource ComboBoxMouseOverBackground}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

使用

1
2
3
4
5
<ComboBox Style="{StaticResource ComboBoxStyle}"
Width="200"
ItemsSource="{Binding TimeOpts}"
Height="36">
</ComboBox>