WPF ListBox的进阶使用(一)
公司项目有个需求,UI界面支持动态平均分割界面,想了想便想到用ListBox来实现,用UniformGrid作为ListBox的ItemsPanelTemplate,通过动态改变UniformGrid的Columns属性,可以动态分割界面。具体实现如下所示:
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}"> 10 <ListBox.ItemsPanel> 11 <ItemsPanelTemplate> 12 <UniformGrid Columns="{Binding Colums}" IsItemsHost="True"/> 13 </ItemsPanelTemplate> 14 </ListBox.ItemsPanel> 15 <ListBox.ItemContainerStyle> 16 <Style TargetType="{x:Type ListBoxItem}"> 17 <Setter Property="Template"> 18 <Setter.Value> 19 <ControlTemplate TargetType="{x:Type ListBoxItem}"> 20 <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Green" BorderBrush="Yellow" BorderThickness="1"> 21 <TextBlock Text="{Binding CameraName}" HorizontalAlignment="Center" VerticalAlignment="Center"/> 22 </Border> 23 </ControlTemplate> 24 </Setter.Value> 25 </Setter> 26 </Style> 27 </ListBox.ItemContainerStyle> 28 </ListBox> 29 </Grid> 30 </Window>
对应的ViewModel层代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Linq; 5 using System.Runtime.CompilerServices; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace WpfDemo 10 { 11 public abstract class NotifyPropertyBase : INotifyPropertyChanged 12 { 13 protected void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 14 { 15 if (object.Equals(storage, value)) return; 16 storage = value; 17 this.OnPropertyChanged(propertyName); 18 } 19 20 protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 21 { 22 if (this.PropertyChanged != null) 23 { 24 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 25 } 26 } 27 28 public event PropertyChangedEventHandler PropertyChanged; 29 } 30 }
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 timer = new DispatcherTimer(); 19 timer.Interval = new TimeSpan(0, 0, 1); 20 timer.Tick += timer_Tick; 21 timer.Start(); 22 } 23 24 private int count = 0; 25 void timer_Tick(object sender, EventArgs e) 26 { 27 var temp = new WndViewModel() 28 { 29 CameraName = string.Format("Camera {0}", ++count), 30 }; 31 DataSource.Add(temp); 32 Console.WriteLine(temp.CameraName); 33 if (count <= 6) 34 { 35 Colums = count; 36 } 37 else if (count > 100) 38 { 39 count = 0; 40 DataSource.Clear(); 41 Colums = 1; 42 } 43 } 44 45 private int colums; 46 public int Colums 47 { 48 get { return colums; } 49 set 50 { 51 SetProperty(ref colums, value); 52 } 53 } 54 55 private ObservableCollection<WndViewModel> dataSource; 56 public ObservableCollection<WndViewModel> DataSource 57 { 58 get { return dataSource; } 59 set 60 { 61 SetProperty(ref dataSource, value); 62 } 63 } 64 } 65 }
软件运行的效果: