WPF DEV實現手風琴效果


說明

最近用WPF+DevExpress做項目時,需要做一個類似手風琴的效果,效果的界面如下。因為沒有現成的控件,需要自定義模板,所以寫了一個Demo和大家分享,項目中可以根據實際情況使用。如果你用不同的方式達到了同樣的效果,歡迎一起交流,共同進步。

需求

思路

WPF開發項目的時候,一定要記住一個原則,即數據驅動程序,在WPF中,數據永遠是主要的地位,仔細分析上面的數據,可得出如下的結構

Group1

  ParmName1   ParmValue1

  ParmName2   ParmValue2

Group2

  ParmName1   ParmValue1

  ParmName2   ParmValue2

  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輕松的將數據源綁定到控件上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM