原文: WPF DEV實作手風琴效果
說明
最近用WPF+DevExpress做項目時,需要做一個類似手風琴的效果,效果的界面如下。因為沒有現成的控件,需要自定義模闆,是以寫了一個Demo和大家分享,項目中可以根據實際情況使用。如果你用不同的方式達到了同樣的效果,歡迎一起交流,共同進步。
需求
思路
WPF開發項目的時候,一定要記住一個原則,即資料驅動程式,在WPF中,資料永遠是主要的地位,仔細分析上面的資料,可得出如下的結構
Group1
ParmName1 ParmValue1
ParmName2 ParmValue2
Group2
ParmNameN ParmValueN
外層的Group資料是一組資料,内層的Info資料也是一組資料,且每一組資料的資料類型相同。WPF中,第一反應想起來的應該是ItemsControl,是以外層應該是一個類似ListBox的控件,内層的類似GridControl的控件,同時還要具有手風琴的效果,這時候就要重寫ListBoxItem的樣式了。接下來,我們就用ItemsControl+Template來實作我們想要的效果。
源碼
<Window x:Class="TestListBox.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:TestListBox"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="350">
<Window.Resources>
<DataTemplate x:Key="NavBarItemContentTemplate">
<dxg:GridControl x:Name="GridAttribute" MaxHeight="500" ItemsSource="{Binding}">
<dxg:GridControl.Columns>
<dxg:GridColumn FieldName="ParmName"></dxg:GridColumn>
<dxg:GridColumn FieldName="ParmValue"></dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.View>
<dxg:TableView x:Name="ViewSimulate" AutoWidth="True" ShowIndicator="False" ShowGroupPanel="False" AllowEditing="True"
AllowColumnFiltering="False" IsColumnMenuEnabled="False"
VerticalScrollbarVisibility="Auto"
ShowColumnHeaders="false"/>
</dxg:GridControl.View>
</dxg:GridControl>
</DataTemplate>
<Style x:Key="ListBoxEditSyle" TargetType="{x:Type dxe:ListBoxEditItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<dxn:NavBarControl Name="navBar">
<dxn:NavBarControl.Groups>
<dxn:NavBarGroup Header="{Binding GroupName}">
<!--<dxn:NavBarItem Content="{Binding Parms}" Template="{StaticResource NavBarItemContentTemplate}" />-->
<ContentControl Content="{Binding Parms}" ContentTemplate="{StaticResource NavBarItemContentTemplate}" />
</dxn:NavBarGroup>
</dxn:NavBarControl.Groups>
</dxn:NavBarControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<dxe:ListBoxEdit x:Name="LBAttr" Margin="-10,0,0,0" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="300" Height="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" ShowBorder="False"
ItemContainerStyle="{StaticResource ListBoxEditSyle}" AllowCollectionView="True">
</dxe:ListBoxEdit>
</Grid>
</Window>
背景源碼
資料源的實體類定義
public class ObjAtt
{
public string GroupName { get; set; }
public List<Parm> Parms { get; set; }
}
public class Parm
{
public string ParmName { get; set; }
public string ParmValue { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LBAttr.ItemsSource = InitItemSource();
}
private List<ObjAtt> InitItemSource()
{
List<ObjAtt> objAtts = new List<ObjAtt>();
objAtts.Add(new ObjAtt()
{
GroupName = "大類1",
Parms = new List<Parm>()
{
new Parm() {ParmName = "參數名1",ParmValue = "參數值1"},
new Parm() {ParmName = "參數名2",ParmValue = "參數值2"},
},
});
objAtts.Add(new ObjAtt()
{
GroupName = "大類2",
Parms = new List<Parm>()
{
new Parm() {ParmName = "參數名1",ParmValue = "參數值1"},
new Parm() {ParmName = "參數名2",ParmValue = "參數值2"},
},
});
objAtts.Add(new ObjAtt()
{
GroupName = "大類3",
Parms = new List<Parm>()
{
new Parm() {ParmName = "參數名1",ParmValue = "參數值1"},
new Parm() {ParmName = "參數名2",ParmValue = "參數值2"},
},
});
objAtts.Add(new ObjAtt()
{
GroupName = "大類4",
Parms = new List<Parm>()
{
new Parm() {ParmName = "參數名1",ParmValue = "參數值1"},
new Parm() {ParmName = "參數名2",ParmValue = "參數值2"},
},
});
return objAtts;
}
}
為了達到示範的效果,背景的資料源一開始我就寫死了。實際項目開發中,你可以在ViewModel中寫擷取資料的方法,然後利用WPF中的Binding輕松的将資料源綁定到控件上。