WPF如何用TreeView製做好友列表、播放列表

WPF如何用TreeView製做好友列表、播放列表

 

前言

  TreeView這個控件對於我來講是用得比較多的,之前作的小聊天軟件(好友列表)、音樂播放器(播放列表)、類庫展現器(樹形類結構)等都用的是TreeView,下面以一個好友列表爲例,說明一下製做過程,這個過程能夠搬遷到其餘相似的場景中去(樹形結構的場景)。安全

結果展現

   

製做過程

  一:新建一個WPF工程,我命名爲TreeViewDemo。(這步不解釋)數據結構

  二:準備圖片,就是系統頭像。在工程中新建一個Heads文件夾,而且添加系統頭像圖片,最後不要忘記須要把生成方式改成Resource、不復制,這樣才能用標準的Pack URI的方式來讀取到圖片。(我喜歡用Pack Uri,由於比較通用,安全)  下載頭像ide

  三:好了,資源圖片準備好了之後,來定義數據類,在這裏咱們須要用到兩個類,一個表明好友,一個表明好友列表(對應的音樂播放器就是音樂和音樂列表)。佈局

  1.Friend(好友)學習

class Friend
    {
        public Friend(FriendList list)
        {
            this.List = list;
        }
        //頭像的路徑
        public String HeadPath { set; get; }
        //好友名字
        public String Name { set; get; }
        //簽名
        public String Autograph { set; get; }

        public FriendList List { set; get; }

    }

 

  2.FriendList(好友列表)
測試

 

class FriendList
    {
        public FriendList(String name)
        {
            this.ListName = name;
        }
        public String ListName { set; get; }

        private ObservableCollection<Friend> _friends = new ObservableCollection<Friend>();
        public ObservableCollection<Friend> Friends
        {
            private set{}
            get
            {
                return _friends;
            }
        }

        public void AddFriend(Friend newFriend)
        {
            _friends.Add(newFriend);
        }

        public void RemoveFriend(Friend friend)
        {
            _friends.Remove(friend);
        }
    }

 

  四:這一步是重點,就是在一個TreeView的節點中,如何去區分Friend和FriendList呢?我使用模板,我分別爲Friend和FriendList定義屬於它們各自的模板,一塊兒定義在一個字典中,新建一個字典,我命名爲GlobeDictionary。這裏應該要用的是數據模板(DataTemplate),系統有一個數據模板叫HierarchicalDataTemplate,這個模板專門用於有頭部和子數據的數據結構的,用在這個TreeView中恰好合適。this

 

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:TreeViewDemo">

    <HierarchicalDataTemplate DataType="{x:Type local:FriendList}" ItemsSource="{Binding Path=Friends,UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" x:Key="ListTemple" >
        <Border x:Name="bord" Margin="-1,-1,0,-1">
            <TextBlock Text="{Binding Path=ListName, Mode=TwoWay}" HorizontalAlignment="Left" Width="227" Padding="2" FontSize="15"></TextBlock>
        </Border>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type local:Friend}"  x:Key="FriendTemple">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="40"></ColumnDefinition>
                <ColumnDefinition Width="150"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Path=HeadPath}" ></Image>
            <StackPanel Orientation="Horizontal" Grid.Column="1" Margin="6,2,2,2">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Path=Name}"  Height="25" HorizontalAlignment="Left" ></TextBlock>
                    <TextBlock Text="{Binding Path=Autograph}"  Height="20" HorizontalAlignment="Left"></TextBlock>
                </StackPanel>
            </StackPanel>
        </Grid>
    </HierarchicalDataTemplate>
    
</ResourceDictionary>

 

  (注意:由於須要再這裏引用自定義類,因此命名空間local的引入必定要正確,衝上面的定義能夠看出,好友列表只顯示名字,好友就用Grid來組織一個類QQ的佈局,頭像,簽名等。)spa

 

  五:主界面。code

  主界面比較簡單,在這個Demo中,只使用TreeView控件。component

<Window x:Class="TreeViewDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TreeViewDemo"
        Title="MainWindow" Height="401" Width="305">
    <Grid>
        <TreeView x:Name="ListTV" ></TreeView>
    </Grid>
</Window>

  

  六:有了軀殼,咱們填入靈魂(數據綁定和數據模板應用)。

  模板有兩個,直接填充TreeView的ItemTemplate屬性是不行的,可是WPF中有一個思想很重要(Selector、Converter等),在TreeView中有一個屬性ItemTemplateSelector。因此,新建一個Selector類,繼承DataTemplateSelector:

 

class FriendOrListTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            ResourceDictionary directory = new ResourceDictionary();
            directory.Source = new Uri("pack://Application:,,,/GlobeDictionary.xaml", UriKind.RelativeOrAbsolute);//使用pack uri載入模板字典
            if (item != null && item is FriendList)
            {
                return directory["ListTemple"] as DataTemplate;
            }
            return directory["FriendTemple"] as DataTemplate;
        }
    }

 

  首先使用pack uri加載位於當前exe程序集中的字典資源(若是加載不了,請將字典生成方式改成Resource),而後根據傳入的數據類型來返回對應的DataTemplate,這樣就能有效的自動選擇模板。

  模板能自動選擇了,另外數據怎麼提供呢,咱們使用在WPF中最經常使用的DataContext綁定來填充ItemsSource。下面看主界面的完整代碼。

<Window x:Class="TreeViewDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TreeViewDemo"
        Title="MainWindow" Height="401" Width="305">
    <Grid>
        <Grid.Resources>
            <local:FriendOrListTemplateSelector x:Key="Myselector"></local:FriendOrListTemplateSelector>
        </Grid.Resources>
        <TreeView x:Name="ListTV" 
                  ItemsSource="{Binding Path=DataContext, Mode=TwoWay,RelativeSource={RelativeSource Mode=Self}}"
                  ItemTemplateSelector="{StaticResource Myselector}" >
        </TreeView>
    </Grid>
</Window>

 

  這裏的命名空間local是FriendOrListTemplateSelector所在的命名空間中,請填寫對。最後在主界面的代碼中加入數據,測試一下。

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ObservableCollection<FriendList> Root = new ObservableCollection<FriendList>();
            FriendList listOne = new FriendList("高中同窗");
            Friend friend1 = new Friend(listOne) { Autograph = "今天很開心,遇到了XX", HeadPath = "Heads/h1.png", Name = "天煞" };
            Friend friend2 = new Friend(listOne) { Autograph = "非通常的感受", HeadPath = "Heads/h2.png", Name = "Basx" };
            Friend friend3 = new Friend(listOne) { Autograph = "WER", HeadPath = "Heads/h3.png", Name = "Paul" };
            Friend friend4 = new Friend(listOne) { Autograph = "~終於完成做業了~~!", HeadPath = "Heads/h4.png", Name = "孤星月" };
            listOne.AddFriend(friend1);
            listOne.AddFriend(friend2);
            listOne.AddFriend(friend3);
            listOne.AddFriend(friend4);
            FriendList listTwo = new FriendList("大一");
            Friend friend5 = new Friend(listOne) { Autograph = "你的存在", HeadPath = "Heads/h5.png", Name = "菲菲" };
            listTwo.AddFriend(friend5);
            Root.Add(listOne);
            Root.Add(listTwo);
            this.ListTV.DataContext = Root;
        }
    }

 

  大功告成~!

總結

  過程比較簡單,可是最重要的是學習其方法,有幾點通用的知識須要注意的:

    1.Xaml中須要使用自定義類的時候,須要在頭部xmlns中添加一項,而且確保命名空間是對的。

    2.Pack URI的使用,任何資源的引用均可以使用Pack URI,下面舉兩個例子:

      *pack://Application:,,,/路徑/路徑/文件名(帶後綴)    <-這種方式是引用當前程序集的Resouce資源的。

      *pack://Application:,,,/引用的程序集名稱;component/路徑/路徑/文件名(帶後綴)<-這種方式是引用其餘程序集的Resouce資源的。

    3.選擇器(Selecter),轉換器(Converter)等的思想要深刻理解。

    4.數據模板是爲數據定製外觀,例如這裏就爲Friend和FriendList定製了外觀了。

                                                完整Demo下載

相關文章
相關標籤/搜索