文章目錄
該樣本完成了如下功能:
ListBox綁定了一個資料來源,該資料來源的資料應該是可變的(樣本中暫時寫死)
當滑鼠移動到ListBoxItem上時,會出現一個Button——Delete,單擊Button會刪除該ListBoxItem。
因此本樣本有兩個核心之處:
1.ListBoxItem的Style的定製
2.資料來源的綁定和單擊按鈕對應的邏輯。
貼代碼:XAML
<Windowxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Class="ListBoxWPF.MainWindow"x:Name="Window"Title="MainWindow"Width="640" Height="480"><Window.Resources><Style TargetType="{x:Type ListBoxItem}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ListBoxItem}"><Grid Background="Violet"><VisualStateManager.VisualStateGroups><VisualStateGroup x:Name="CommonStates"><VisualState x:Name="Normal"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ButtonDelete"><DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/><DiscreteObjectKeyFrame KeyTime="0:0:0.001" Value="{x:Static Visibility.Collapsed}"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="MouseOver"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ButtonDelete"><DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}"/><DiscreteObjectKeyFrame KeyTime="0:0:0.001" Value="{x:Static Visibility.Visible}"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="Disabled"/></VisualStateGroup></VisualStateManager.VisualStateGroups><Grid.RowDefinitions><RowDefinition Height="Auto"></RowDefinition><RowDefinition Height="Auto"></RowDefinition></Grid.RowDefinitions><TextBlock Text="{Binding T1}" FontSize="36"></TextBlock><Button Grid.Row="1" Width="100" Height="24" HorizontalAlignment="Center"Name="ButtonDelete" Click="ButtonDelete_Click">Delete</Button></Grid></ControlTemplate></Setter.Value></Setter></Style></Window.Resources><Grid x:Name="LayoutRoot"><ListBox x:Name="ListBoxTest"></ListBox></Grid></Window>
cs部分:
/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){this.InitializeComponent();ObservableCollection<TestDataItem> source = new ObservableCollection<TestDataItem>();for (int i = 0; i < 100; i++){source.Add(new TestDataItem() { T1 = i.ToString() });}ListBoxTest.ItemsSource = source;this.Loaded+=new System.Windows.RoutedEventHandler(MainWindow_Loaded);// Insert code required on object creation below this point.}private void MainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e){// TODO: Add event handler implementation here.}private void ButtonDelete_Click(object sender, RoutedEventArgs e){Button btn = sender as Button;if (btn == null){throw new InvalidOperationException("btn is Null");}ListBoxItem lbi = FindParent<ListBoxItem>(btn);if (lbi != null){TestDataItem tdi = ListBoxTest.ItemContainerGenerator.ItemFromContainer(lbi) as TestDataItem;if (tdi != null){(ListBoxTest.ItemsSource as ICollection<TestDataItem>).Remove(tdi);}}}static T FindParent<T>(DependencyObject d) where T : DependencyObject{DependencyObject parent = d;while (parent != null){parent = VisualTreeHelper.GetParent(parent);if (parent != null && (parent.GetType() == typeof(T))){return parent as T;}}return parent as T;}}public class TestDataItem :INotifyPropertyChanged{private string _t1;public string T1{get{return _t1;}set{_t1=value;NotifyPropertyChanged("T1");}}#region INotifyPropertyChanged Memberspublic event PropertyChangedEventHandler PropertyChanged;private void NotifyPropertyChanged(string proName){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(proName));}}#endregion}