WPF 一种带有多个子集的类ComBox 解决方法
在最近的工作中遇到很多,类似这种layUI风格的Combox:
因为WPF原本的控件,并不具备这种功能,尝试重写Combox的模板,发现无从下手。
于是尝试从多个控件组合来实现这个功能。
这里使用了Popup 来存放数据,发现还不错。
将popup分为三列,每个列的列宽设置位自动,当点击其中一个选项的时候,检索所选,根据字典查到数据,再加载其他列。
即可实现这种效果
代码如下:
UI:


<Button x:Name="btn1"
Height="54"
Margin="0,10,0,0"
Click="Button_Click">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Background="Transparent"
CornerRadius="15"
BorderBrush="#6B778D"
BorderThickness="1">
<Grid>
<TextBlock
Text="▼"
Margin="0,0,5,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="White"
FontSize="20" />
<TextBlock
Text="{Binding Shell6PageModel.DetailedAddress}"
Margin="10,0,0,0"
VerticalAlignment="Center"
Foreground="White"
FontSize="32" />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Popup x:Name="pop1"
Width="{Binding ElementName=btn1, Path=ActualWidth}"
Height="260"
AllowsTransparency="True"
IsOpen="False"
Placement="Bottom"
PlacementTarget="{Binding ElementName=btn1}"
PopupAnimation="Slide"
StaysOpen="False">
<Grid>
<Border
Background="Gray"
Opacity="0.9"
BorderBrush="Gray"
BorderThickness="1"
CornerRadius="8" /> <Border>
<Grid HorizontalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> <Grid Grid.Column="0">
<ListBox
ItemsSource="{Binding Countries}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0"> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedCountry}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.countryCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="0" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="1">
<ListBox
ItemsSource="{Binding Shengs}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0"> <ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border x:Name="bord1" />
<ContentPresenter VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedSheng}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.shengCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="1" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="2">
<ListBox
ItemsSource="{Binding Cities}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid> <ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedCity}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.cityCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
VerticalAlignment="Center"
Foreground="White"
FontSize="36"
GroupName="2" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> <Grid Grid.Column="3">
<ListBox
ItemsSource="{Binding Areas}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid>
<Border x:Name="bord1" />
<ContentPresenter />
</Grid> <ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bord1" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle> <ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding DetailedArea}"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Shell6Page}}, Path=DataContext.areaCommand}"
CommandParameter="{Binding}"
Width="100"
Height="35"
Margin="0,5,0,5"
Foreground="White"
FontSize="36"
Click="RadioButton_Click"
GroupName="3" />
</DataTemplate>
</ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </Grid> </Border> </Grid>
</Popup>
Model:


public class Shell6PageModel:ViewModelBase
{
private string detailedAddress;
/// <summary>
/// 详细地址
/// </summary>
public string DetailedAddress
{
get { return detailedAddress; }
set
{
detailedAddress = value; }
} private string area;
/// <summary>
/// 所在地区
/// </summary>
public string Area
{
get { return area; }
set { area = value; }
}
}
ViewModel:


public class Shell6PageViewModel : ViewModelBase
{
Dictionary<string, string> AddressCity = new Dictionary<string, string>();
Dictionary<string, string> AddressArea = new Dictionary<string, string>();
Dictionary<string, string> AddressSheng = new Dictionary<string, string>();
Dictionary<string, string> AddressCountry = new Dictionary<string, string>();
string[] ad; public Shell6PageViewModel()
{
countryCommand = new RelayCommand<Country>(t => GetCountry(t));
shengCommand = new RelayCommand<Sheng>(t => GetSheng(t));
cityCommand = new RelayCommand<City>(t => GetCity(t));
areaCommand = new RelayCommand<Area>(t => GetArea(t)); Shell6PageModel = new Shell6PageModel()
{
Area = EAppEnvironment.informationInfo.Area, DetailedAddress = EAppEnvironment.informationInfo.DetailedAddress };
InitDictionary();
} private void GetArea(Area t)
{
ad[3] = t.DetailedArea;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
} } private void GetCity(City t)
{
Areas.Clear(); ad[2] = t.DetailedCity;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
} foreach (var item in AddressArea)
{
if (t.DetailedCity == item.Value)
{
Areas.Add(new Area { DetailedArea = item.Key }); }
}
} private void GetSheng(Sheng t)
{
Cities.Clear();
Areas.Clear();
ad[1] = t.DetailedSheng;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
}
foreach (var item in AddressCity)
{
if (t.DetailedSheng == item.Value)
{
Cities.Add(new City() { DetailedCity = item.Key }); }
} } private void GetCountry(Country t)
{
Shengs.Clear();
Cities.Clear();
Areas.Clear();
ad = null;
ad = new string[4];
ad[0] = t.DetailedCountry;
Shell6PageModel.DetailedAddress = "";
foreach (var item in ad)
{
Shell6PageModel.DetailedAddress += item;
}
foreach (var item in AddressSheng)
{
if (t.DetailedCountry == item.Value)
{
Shengs.Add(new Sheng() { DetailedSheng = item.Key });
}
}
} private Shell6PageModel shell6PageModel; public Shell6PageModel Shell6PageModel
{
get { return shell6PageModel; }
set { shell6PageModel = value; RaisePropertyChanged(); }
} public RelayCommand<Sheng> shengCommand { get; set; } public RelayCommand<Country> countryCommand { get; set; } public RelayCommand<City> cityCommand { get; set; }
public RelayCommand<Area> areaCommand { get; set; } private ObservableCollection<Country> countries; public ObservableCollection<Country> Countries
{
get { return countries; }
set { countries = value; RaisePropertyChanged(); }
} private ObservableCollection<Sheng> shengs; public ObservableCollection<Sheng> Shengs
{
get { return shengs; }
set { shengs = value; RaisePropertyChanged(); }
} private ObservableCollection<City> cities; public ObservableCollection<City> Cities
{
get { return cities; }
set { cities = value; RaisePropertyChanged(); }
} private ObservableCollection<Area> areas; public ObservableCollection<Area> Areas
{
get { return areas; }
set { areas = value; RaisePropertyChanged(); }
} public void InitDictionary()
{
Countries = new ObservableCollection<Country>();
Shengs = new ObservableCollection<Sheng>();
Cities = new ObservableCollection<City>();
Areas = new ObservableCollection<Area>(); Countries.Add(new Country() { DetailedCountry = "中国" });
Countries.Add(new Country() { DetailedCountry = "国外" }); AddressSheng.Add("湖北1", "中国");
AddressSheng.Add("湖北2", "中国");
AddressSheng.Add("湖北3", "中国");
AddressSheng.Add("湖北4", "中国");
AddressSheng.Add("湖北5", "中国");
AddressSheng.Add("湖北6", "中国");
AddressSheng.Add("湖北7", "中国");
AddressSheng.Add("湖北8", "中国");
AddressSheng.Add("纽约1", "国外");
AddressSheng.Add("纽约2", "国外");
AddressSheng.Add("纽约3", "国外");
AddressSheng.Add("纽约4", "国外");
AddressSheng.Add("纽约5", "国外");
AddressSheng.Add("纽约6", "国外");
AddressSheng.Add("纽约7", "国外");
AddressSheng.Add("纽约8", "国外"); AddressCity.Add("孝感", "湖北1");
AddressCity.Add("武汉", "湖北1");
AddressCity.Add("襄阳", "湖北1");
AddressCity.Add("十堰", "湖北1");
AddressCity.Add("仙桃", "湖北1");
AddressCity.Add("鄂州", "湖北2");
AddressCity.Add("黄冈", "湖北2");
AddressCity.Add("神农架", "湖北2");
AddressCity.Add("黄石", "湖北2");
AddressCity.Add("恩施", "湖北2");
AddressCity.Add("湖南1", "湖北3");
AddressCity.Add("湖南2", "湖北3");
AddressCity.Add("湖南3", "湖北3");
AddressCity.Add("湖南4", "湖北3");
AddressCity.Add("湖南5", "湖北3");
AddressCity.Add("湖南6", "湖北3");
AddressCity.Add("湖南7", "湖北3"); AddressArea.Add("孝感1", "孝感");
AddressArea.Add("孝感2", "孝感");
AddressArea.Add("孝感3", "孝感");
AddressArea.Add("孝感4", "孝感");
AddressArea.Add("孝感5", "孝感");
AddressArea.Add("孝感6", "孝感");
AddressArea.Add("孝感7", "孝感");
AddressArea.Add("孝感8", "孝感"); }
}
WPF 一种带有多个子集的类ComBox 解决方法的更多相关文章
- 16种C语言编译警告(Warning)类型的解决方法
当编译程序发现程序中某个地方有疑问,可能有问题时就会给出一个警告信息.警告信息可能意味着程序中隐含的大错误,也可能确实没有问题.对于警告的正确处理方式应该是:尽可能地消除之.对于编译程序给出的每个警告 ...
- WebService中使用自定义类的解决方法(5种)
转自:http://www.cnblogs.com/lxinxuan/archive/2007/05/24/758317.html Demo下载:http://files.cnblogs.com/lx ...
- CodedUI Test 测试WPF程序,无法获取控件属性值的解决方法
注意注意!ItemStatus 在VS2010的CUIT里面是没有的!需要2013以上的版本才可使用. 公司新程序使用WPF制作,但使用CodedUI Test进行自动化测试的时候,很多控件抓取不到其 ...
- WPF 四种尺寸单位
原文:WPF 四种尺寸单位 像素 px 默认单位可以省略 厘米cm 英寸 in 点 pt 1in = 96px 1cm=96/2.42px 1pt=96/72px
- WPF 平板上按钮点击不触发,鼠标点击触发的两种解决方法
今天运行在windows平板上的程序,有个功能是弹出子窗体,点弹出窗体的关闭按钮,要点好几次才能触发.网上找了找,也有人与我类似的情形. 解决方法如下: public static void Disa ...
- WPF WebBrowser Memory Leak 问题及临时解决方法
首先介绍一下内存泄漏(Memory Leak)的概念,内存泄露是指程序中已动态分配的堆内存由于某种原因未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 最近在使用W ...
- Ubuntu几种常见乱码解决方法
一.网页中的flash乱码: ubuntu默认浏览器是Firefox,但是Ubuntu默认不安装像flash这种带版权的软件,所以当你浏览像youku或网页播放器时,这种带有 flash ...
- Spring Boot Maven Plugin打包异常及三种解决方法:Unable to find main class
[背景]spring-boot项目,打包成可执行jar,项目内有两个带有main方法的类并且都使用了@SpringBootApplication注解(或者另一种情形:你有两个main方法并且所在类都没 ...
- PowerDesigner生成Oracle表名带有引号的解决方法
PowerDesigner生成表名带有引号,如下: /*==============================================================*/ /* Tabl ...
随机推荐
- 第七章节 BJROBOT 选择区域自主构建地图【ROS全开源阿克曼转向智能网联无人驾驶车】
1.把小车平放在地板上,用资料里的虚拟机,打开一个终端 ssh 过去主控端启动roslaunch znjrobot bringup.launch 2.在虚拟机端再打开一个终端,ssh 过去主控端启动r ...
- JVM--理解介绍
JVM?JDK?JRE?关系? JDK(Java Development Kit),它是实际上存在的,它包含JRE+编译.运行等开发工具. JRE(Java Runtime Environment), ...
- Spring Security OAuth2.0认证授权二:搭建资源服务
在上一篇文章[Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://www.cnblogs.com/kuangdaoyizhimei/p/14250374. ...
- 算法设计与分析 - 主定理Master theorem (分治法递推时间复杂度)
英文原版不上了 直接中文 定义 假设有递推关系式T(n)=aT(n/b)+f(n) 其中n为问题规模 a为递推的子问题数量 n/b为每个子问题的规模(假设每个子问题的规模基本一样) f(n)为递推以外 ...
- 坐上JDK8时间SDK的小船,带你遨游UNIX时间戳与时区的小太空~
原文链接:坐上JDK8时间SDK的小船,带你遨游UNIX时间戳与时区的小太空- 一.背景: 最近有一个关于店铺数据实时分析的需求,需要实时统计店铺当天的数据:例如访客数,浏览量.商品排行榜等.由于店铺 ...
- Vue 组件内滚动条 滚到到底部
因为在vue中,某个组件内 使用scrollTop赋值 滚动条没有变化 使用scrollTo 也不行(window.scorllTo 或者dom.scrollTo) 所以可以考虑使用投机取巧的办法: ...
- LeetCode144 二叉树的前序遍历
给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? /** * Defin ...
- Hbase snapshot数据迁移
# 在源集群中创建快照(linux shell) hbase snapshot -t <table_name> -n <snapshot_name> 或(hbase shell ...
- LeetCode454. 四数相加 II
题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...
- BINARY SEARCH 的一点说明
在sap 之abap语言中,有BINARY SEARCH这个查找条件.使用read table 来读取内表时,使用BINARY SEARCH可以大大的提高查找的效率,为什么呢?学过数据库的人会知道 ...