当前位置: 移动技术网 > IT编程>开发语言>.net > WPF ListBox的进阶使用(二)

WPF ListBox的进阶使用(二)

2018年08月31日  | 移动技术网IT编程  | 我要评论

4948游戏盒,偷艳乡村,快递报价

项目中经常使用需要根据搜索条件查询数据,然后用卡片来展示数据。用卡片展示数据时,界面的宽度发生变化,希望显示的卡片数量也跟随变化。wrappanel虽然也可以实现这个功能,但是将多余的部分都留在行尾,十分不美观,最好是能够将多余的宽度平分在每个listboxitem之间,比较美观,也符合项目需求。如下便是我自己实现的panel:

  1 using system;
  2 using system.collections.generic;
  3 using system.linq;
  4 using system.text;
  5 using system.threading.tasks;
  6 using system.windows;
  7 using system.windows.controls;
  8 
  9 namespace wpfdemo
 10 {
 11     public class mywrappanel : panel
 12     {
 13         protected override system.windows.size measureoverride(system.windows.size availablesize)
 14         {
 15             size currentlinesize = new size();
 16             size panelsize = new size();
 17 
 18             foreach (uielement element in base.internalchildren)
 19             {
 20                 element.measure(availablesize);
 21                 size desiredsize = element.desiredsize;
 22 
 23                 if (currentlinesize.width + desiredsize.width > availablesize.width)
 24                 {
 25                     panelsize.width = math.max(currentlinesize.width, panelsize.width);
 26                     panelsize.height += currentlinesize.height;
 27                     currentlinesize = desiredsize;
 28 
 29                     if (desiredsize.width > availablesize.width)
 30                     {
 31                         panelsize.width = math.max(desiredsize.width, panelsize.width);
 32                         panelsize.height += desiredsize.height;
 33                         currentlinesize = new size();
 34                     }
 35                 }
 36                 else
 37                 {
 38                     currentlinesize.width += desiredsize.width;
 39                     currentlinesize.height = math.max(desiredsize.height, currentlinesize.height);
 40                 }
 41             }
 42 
 43             panelsize.width = math.max(currentlinesize.width, panelsize.width);
 44             panelsize.height += currentlinesize.height;
 45 
 46             return panelsize;
 47         }
 48 
 49         protected override system.windows.size arrangeoverride(system.windows.size finalsize)
 50         {
 51             int firstinline = 0;
 52             int linecount = 0;
 53 
 54             size currentlinesize = new size();
 55 
 56             double accumulatedheight = 0;
 57 
 58             uielementcollection elements = base.internalchildren;
 59             double interval = 0.0;
 60             for (int i = 0; i < elements.count; i++)
 61             {
 62 
 63                 size desiredsize = elements[i].desiredsize;
 64 
 65                 if (currentlinesize.width + desiredsize.width > finalsize.width) //need to switch to another line
 66                 {
 67                     interval = (finalsize.width - currentlinesize.width) / (i - firstinline + 2);
 68                     arrangeline(accumulatedheight, currentlinesize.height, firstinline, i, interval);
 69 
 70                     accumulatedheight += currentlinesize.height;
 71                     currentlinesize = desiredsize;
 72 
 73                     if (desiredsize.width > finalsize.width) //the element is wider then the constraint - give it a separate line                    
 74                     {
 75                         arrangeline(accumulatedheight, desiredsize.height, i, ++i, 0);
 76                         accumulatedheight += desiredsize.height;
 77                         currentlinesize = new size();
 78                     }
 79                     firstinline = i;
 80                     linecount++;
 81                 }
 82                 else //continue to accumulate a line
 83                 {
 84                     currentlinesize.width += desiredsize.width;
 85                     currentlinesize.height = math.max(desiredsize.height, currentlinesize.height);
 86                 }
 87             }
 88 
 89             if (firstinline < elements.count)
 90             {
 91                 if (linecount == 0)
 92                 {
 93                     interval = (finalsize.width - currentlinesize.width) / (elements.count - firstinline + 1);
 94                 }
 95                 arrangeline(accumulatedheight, currentlinesize.height, firstinline, elements.count, interval);
 96             }
 97                 
 98 
 99             return finalsize;
100         }
101 
102         private void arrangeline(double y, double lineheight, int start, int end, double interval)
103         {
104             double x = 0;
105             uielementcollection children = internalchildren;
106             for (int i = start; i < end; i++)
107             {
108                 x += interval;
109                 uielement child = children[i];
110                 child.arrange(new rect(x, y, child.desiredsize.width, lineheight));
111                 x += child.desiredsize.width;
112             }
113         }
114     }
115 }

接下来,便是将这个mywrappanel作为listbox的itemspaneltemplate即可:

 1 <window x:class="wpfdemo.mainwindow"
 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:comm="clr-namespace:wpfdemo.commoncontrols;assembly=wpfdemo.commoncontrols"
 5         xmlns:local="clr-namespace:wpfdemo"
 6         title="mainwindow" height="350" width="525">
 7     
 8     <grid>
 9         <listbox itemssource="{binding datasource}" scrollviewer.horizontalscrollbarvisibility="disabled"
10                  verticalalignment="center" borderthickness="0">
11             <listbox.itemspanel>
12                 <itemspaneltemplate>
13                     <local:mywrappanel isitemshost="true"/>
14                 </itemspaneltemplate>
15             </listbox.itemspanel>
16             <listbox.itemcontainerstyle>
17                 <style targettype="{x:type listboxitem}">
18                     <setter property="template">
19                         <setter.value>
20                             <controltemplate targettype="{x:type listboxitem}">
21                                 <border horizontalalignment="stretch" verticalalignment="stretch" background="green" borderbrush="yellow" borderthickness="1">
22                                     <textblock text="{binding cameraname}" width="100" horizontalalignment="center" verticalalignment="center"/>
23                                 </border>
24                             </controltemplate>
25                         </setter.value>
26                     </setter>
27                 </style>
28             </listbox.itemcontainerstyle>
29             <listbox.style>
30                 <style targettype="{x:type listbox}">
31                     
32                 </style>
33             </listbox.style>
34         </listbox>
35     </grid>
36 </window>

界面对应的viewmodel:

 1 using system;
 2 using system.collections.generic;
 3 using system.collections.objectmodel;
 4 using system.linq;
 5 using system.text;
 6 using system.threading.tasks;
 7 using system.windows.threading;
 8 
 9 namespace wpfdemo
10 {
11     public class mainwindowvm : notifypropertybase
12     {
13         private dispatchertimer timer;
14         public mainwindowvm()
15         {
16             datasource = new observablecollection<wndviewmodel>();
17             colums = 1;
18             for(int i =0; i < 60; ++i)
19             {
20                 var temp = new wndviewmodel()
21                 {
22                     cameraname = string.format("camera {0}", ++count),
23                 };
24                 datasource.add(temp);
25             }
26             //timer = new dispatchertimer();
27             //timer.interval = new timespan(0, 0, 1);
28             //timer.tick += timer_tick;
29             //timer.start();
30         }
31 
32         private int count = 0;
33         void timer_tick(object sender, eventargs e)
34         {
35             var temp = new wndviewmodel()
36             {
37                 cameraname = string.format("camera {0}", ++count),
38             };
39             datasource.add(temp);
40             console.writeline(temp.cameraname);
41             if (count <= 6)
42             {
43                 colums = count;
44             }
45             else if (count > 100)
46             {
47                 count = 0;
48                 datasource.clear();
49                 colums = 1;
50             }
51         }
52 
53         private int colums;
54         public int colums
55         {
56             get { return colums; }
57             set
58             {
59                 setproperty(ref colums, value);
60             }
61         }
62 
63         private observablecollection<wndviewmodel> datasource;
64         public observablecollection<wndviewmodel> datasource
65         {
66             get { return datasource; }
67             set
68             {
69                 setproperty(ref datasource, value);
70             }
71         }
72     }
73 }

运行结果:

拉伸后:

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网