激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C# - WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果

WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果

2022-02-23 13:29小明GG C#

TreeView控件在項(xiàng)目中使用比較頻繁,下面這篇文章主要給大家介紹了關(guān)于WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

一、前言

treeview這個(gè)控件對(duì)于我來(lái)說(shuō)是用得比較多的,以前做的小聊天軟件(好友列表)、音樂(lè)播放器(播放列表)、類庫(kù)展示器(樹形類結(jié)構(gòu))等都用的是treeview,普通的treeview并不能滿足我們的需求。因此我們需要滴對(duì)treeview進(jìn)行改造。下面的內(nèi)容將介紹仿qq聯(lián)系人treeview樣式及treeview數(shù)據(jù)綁定方法。

二、treeview仿qq聯(lián)系人列表

準(zhǔn)確的說(shuō)不是仿qq聯(lián)系人列表,這個(gè)treeview樣式作為組織架構(gòu)來(lái)使用更好。廢話不多說(shuō),先看效果:

WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果

 2.1、基本思路

像這種聯(lián)系人列表一般涉及到多層級(jí)數(shù)據(jù),而且有很多數(shù)據(jù)是需要?jiǎng)討B(tài)更新的,如果通過(guò)手動(dòng)一條條增加數(shù)據(jù)反而更復(fù)雜,而且不方便。因此為了綁定數(shù)據(jù)方便我們使用分層模板hierarchicaldatatemplate。

分層模板中存在兩種樣式,一種是分組樣式,一種是人員樣式。不管是分組還是人員綁定的都是對(duì)象,這樣我們?cè)趯?duì)象中添加一個(gè)屬性來(lái)辨別是否為分組-isgrouping。

默認(rèn)的treeview控件四周會(huì)有邊距,因此需要設(shè)置下treeview的樣式。另外鼠標(biāo)經(jīng)過(guò)和鼠標(biāo)選中的背景色需要變化,因此還需要設(shè)置treeviewitem的樣式。

根據(jù)思路,我們需要設(shè)置三個(gè)樣式,treeview樣式,treeviewitem樣式,hierarchicaldatatemplate分層模板樣式。另外為了自動(dòng)計(jì)算下一級(jí)的邊距,我們需要添加一個(gè)轉(zhuǎn)換器indentconverter。還需要一個(gè)轉(zhuǎn)換器需要將布爾類型的isgrouping轉(zhuǎn)換為visibility,還需要一個(gè)轉(zhuǎn)換器來(lái)對(duì)visibility取反。

這樣三個(gè)樣式,三個(gè)轉(zhuǎn)換器。就可以實(shí)現(xiàn)我們上面的效果,另外還可以進(jìn)行動(dòng)態(tài)數(shù)據(jù)綁定。

2.2、樣式代碼

hierarchicaldatatemplate分層模板樣式代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<hierarchicaldatatemplate x:key="itemnode" itemssource="{binding children,mode=twoway}">
   <grid background="transparent">
    <grid.resources>
     <convert:booltovisible x:key="booltovisible"/>
     <convert:visibletoreverse x:key="visibletoreverse"/>
    </grid.resources>
    <grid minheight="30" x:name="userinfo" background="transparent" margin="-5 0 0 0" visibility="{binding visibility,elementname=groupinginfo,converter={staticresource visibletoreverse}}">
     <grid height="50" x:name="grid">
      <border background="#62acf9" width="40" height="40" cornerradius="4" horizontalalignment="left" margin="0 0 0 0">
       <textblock text="{binding surname}" fontsize="23" foreground="white" verticalalignment="center" horizontalalignment="center"/>
      </border>
      <textblock text="{binding name}" margin="50 7 0 0" fontsize="13"/>
      <textblock text="{binding info}" foreground="#808080" margin="50 30 0 0"/>
      <textblock text="{binding count,stringformat={}{0}人}" foreground="#808080" horizontalalignment="right" verticalalignment="center" margin="0 0 5 0"/>
     </grid>
    </grid>
    <stackpanel minheight="25" x:name="groupinginfo" orientation="horizontal" background="transparent" horizontalalignment="left" visibility="{binding isgrouping,converter={staticresource booltovisible}}">
 
     <textblock text="{binding displayname}" margin="3 0" verticalalignment="center" horizontalalignment="left"/>
    </stackpanel>
   </grid>
  </hierarchicaldatatemplate>

treeviewitem樣式代碼

?
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
<style x:key="defaulttreeviewitem" targettype="{x:type treeviewitem}">
   <setter property="minheight" value="25" />
   <setter property="background" value="transparent" />
   <setter property="snapstodevicepixels" value="true" />
 
   <setter property="margin" value="0" />
   <setter property="template">
    <setter.value>
     <controltemplate targettype="{x:type treeviewitem}">
      <controltemplate.resources>
       <convert:indentconverter x:key="indentconverter"/>
      </controltemplate.resources>
      <grid background="transparent">
       <grid.rowdefinitions>
        <rowdefinition/>
        <rowdefinition/>
       </grid.rowdefinitions>
       <border name="itembackground" background="{templatebinding background}"
        borderbrush="{templatebinding borderbrush}"
        borderthickness="{templatebinding borderthickness}"
        padding="{templatebinding padding}">
        <grid background="transparent">
         <grid x:name="itemroot" margin="{binding converter={staticresource indentconverter},relativesource={relativesource templatedparent}}" background="transparent">
          <grid.columndefinitions>
           <columndefinition width="16" />
           <columndefinition width="*"/>
          </grid.columndefinitions>
 
          <togglebutton x:name="expander" horizontalalignment="left" clickmode="press" ischecked="{binding isexpanded, relativesource={relativesource templatedparent}}">
           <togglebutton.style>
            <style targettype="{x:type togglebutton}">
             <setter property="focusable" value="false"/>
             <setter property="width" value="16"/>
             <setter property="height" value="16"/>
             <setter property="template">
              <setter.value>
               <controltemplate targettype="{x:type togglebutton}">
                <border background="transparent" height="16" padding="5" width="16">
                 <path x:name="expandpath" data="m0,0 l0,6 l6,0 z" fill="#66645e" stroke="#66645e">
                  <path.rendertransform>
                   <rotatetransform angle="135" centery="3" centerx="3"/>
                  </path.rendertransform>
                 </path>
                </border>
                <controltemplate.triggers>
                 <trigger property="ischecked" value="true">
                  <setter property="rendertransform" targetname="expandpath">
                   <setter.value>
                    <rotatetransform angle="180" centery="3" centerx="3"/>
                   </setter.value>
                  </setter>
                  <setter property="fill" targetname="expandpath" value="#66645e"/>
                  <setter property="stroke" targetname="expandpath" value="#66645e"/>
                 </trigger>
                 <trigger property="ismouseover" value="true">
                  <setter property="stroke" targetname="expandpath" value="#66645e"/>
                  <setter property="fill" targetname="expandpath" value="#66645e"/>
                 </trigger>
                 <multitrigger>
                  <multitrigger.conditions>
                   <condition property="ismouseover" value="true"/>
                   <condition property="ischecked" value="true"/>
                  </multitrigger.conditions>
                  <setter property="stroke" targetname="expandpath" value="#66645e"/>
                  <setter property="fill" targetname="expandpath" value="#66645e"/>
                 </multitrigger>
                </controltemplate.triggers>
               </controltemplate>
              </setter.value>
             </setter>
            </style>
           </togglebutton.style>
          </togglebutton>
          <contentpresenter grid.column="1" x:name="part_header" contentsource="header"
             horizontalalignment="stretch" >
 
          </contentpresenter>
         </grid>
        </grid>
 
       </border>
       <itemspresenter x:name="itemshost" grid.row="1"/>
      </grid>
 
      <controltemplate.triggers>
       <datatrigger binding="{binding isgrouping}" value="false">
        <setter property="visibility" targetname="expander" value="hidden"/>
       </datatrigger>
       <trigger property="hasitems" value="false">
        <setter property="visibility" targetname="expander" value="collapsed"/>
       </trigger>
       <trigger property="isexpanded" value="false">
        <setter property="visibility" targetname="itemshost" value="collapsed"/>
       </trigger>
 
       <trigger property="isselected" value="true">
        <setter property="background" targetname="itembackground" value="#fae388"/>
       </trigger>
       <multitrigger>
        <multitrigger.conditions>
         <condition property="isfocused" value="false"/>
         <condition sourcename="itembackground" property="ismouseover" value="true"/>
        </multitrigger.conditions>
        <setter property="background" value=" #fceeb9" targetname="itembackground"/>
       </multitrigger>
       <trigger property="isenabled" value="false">
        <setter property="foreground" value="{dynamicresource {x:static systemcolors.graytextbrushkey}}"/>
       </trigger>
      </controltemplate.triggers>
     </controltemplate>
    </setter.value>
   </setter>
  </style>

treeview樣式代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style x:key="defaulttreeview" targettype="{x:type treeview}">
   <setter property="scrollviewer.cancontentscroll" value="true" />
   <setter property="virtualizingstackpanel.isvirtualizing" value="true"></setter>
   <setter property="virtualizingstackpanel.virtualizationmode" value="recycling" />
   <setter property="scrollviewer.isdeferredscrollingenabled" value="false" />
   <setter property="itemcontainerstyle" value="{staticresource defaulttreeviewitem}"></setter>
   <setter property="padding" value="0"/>
   <setter property="itemspanel">
    <setter.value>
     <itemspaneltemplate>
      <virtualizingstackpanel isitemshost="true" margin="0"/>
     </itemspaneltemplate>
    </setter.value>
   </setter>
  </style>

2.3、轉(zhuǎn)換器代碼

?
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
public class indentconverter : ivalueconverter
 {
  public object convert(object value, type targettype, object parameter, cultureinfo culture)
  {
   double colunwidth = 10;
   double left = 0.0;
   uielement element = value as treeviewitem;
   while (element.gettype() != typeof(treeview))
   {
    element = (uielement)visualtreehelper.getparent(element);
    if (element.gettype() == typeof(treeviewitem))
     left += colunwidth;
   }
   return new thickness(left, 0, 0, 0);
  }
 
  public object convertback(object value, type targettype, object parameter, cultureinfo culture)
  {
   throw new notimplementedexception();
  }
 
 }
 
 public class booltovisible : ivalueconverter
 {
  public object convert(object value, type targettype, object parameter, cultureinfo culture)
  {
   if ((bool)value)
    return visibility.visible;
   else
    return visibility.collapsed;
  }
 
  public object convertback(object value, type targettype, object parameter, cultureinfo culture)
  {
   throw new notimplementedexception();
  }
 }
 
 public class visibletoreverse : ivalueconverter
 {
  public object convert(object value, type targettype, object parameter, cultureinfo culture)
  {
   if ((visibility)value == visibility.visible)
    return visibility.collapsed;
   else
    return visibility.visible;
  }
 
  public object convertback(object value, type targettype, object parameter, cultureinfo culture)
  {
   throw new notimplementedexception();
  }
 }

2.4、引用示例

?
1
2
<treeview x:name="treevieworg" borderthickness="1" borderbrush="#bbb" background="transparent" width="280" height="500" margin="10" itemtemplate="{staticresource itemnode}" style="{staticresource defaulttreeview}">
  </treeview>

2.5、初始化數(shù)據(jù)源及綁定對(duì)象

?
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
public mainwindow()
  {
   initializecomponent();
   orglist = new observablecollection<orgmodel>()
   {
    new orgmodel()
    {
     isgrouping=true,
     displayname="單位名稱(3/7)",
     children=new observablecollection<orgmodel>()
     {
      new orgmodel(){
       isgrouping=true,
       displayname="未分組聯(lián)系人(2/4)",
       children=new observablecollection<orgmodel>()
       {
        new orgmodel(){
         isgrouping=false,
         surname="劉",
         name="劉棒",
         info="我要走向天空!",
         count=3
        }
       }
      }
     },
    }
 
   };
   treevieworg.itemssource = orglist;
  }
 
  public observablecollection<orgmodel> orglist { get; set; }
 
  public class orgmodel
  {
   public bool isgrouping { get; set; }
   public observablecollection<orgmodel> children { get; set; }
   public string displayname { get; set; }
   public string surname { get; set; }
   public string name { get; set; }
   public string info { get; set; }
   public int count { get; set; }
  }

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:http://www.cnblogs.com/xiaomingg/p/8765802.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲片在线 | 久久夜夜视频 | 国产成人高清成人av片在线看 | 日韩av电影在线观看 | 成人毛片100免费观看 | 日本黄色a视频 | 竹内纱里奈和大战黑人 | 欧美日本色 | 手机免费看一级片 | 黄色片免费在线 | 欧洲精品久久久久69精品 | 国产一级一国产一级毛片 | 成人国产精品久久 | 免费一级毛片在线播放视频老 | 毛片免费在线播放 | 成年人观看免费视频 | 久久综合网址 | 欧美熟videos肥婆 | 久久在现视频 | 国产免费高清 | www.三区| 国产精品视频久久久 | 斗罗破苍穹在线观看免费完整观看 | 中文字幕在线观看视频www | 国产在线1区 | 黄色片网站免费观看 | 操操电影| 日韩黄色片免费看 | 日本在线观看高清完整版 | 午夜视频亚洲 | 黄网站在线观 | 国产一区在线免费 | 日韩欧美动作影片 | 欧美一区二区三区四区五区动图 | 欧美成人精品欧美一级乱黄 | 久久老司机精品视频 | 欧美成人小视频 | 亚洲午夜在线视频 | 在线成人精品视频 | 亚洲精品久久久久久 | 久久免费视频精品 |