ListBoxの一部のアイテムは、ボタンとTextBoxを含むテンプレートを使用しています。リストからこれらのアイテムを選択することは不可能であるが、ボタンを操作することは可能であるようにするにはどうすればよいですか?
編集:
このテンプレートを使用しているアイテムだけでなく、このリストで他のアイテムを選択できるようにする必要があります。
ListBoxの代わりにItemsControlを使用する
ListBoxItemに添付されたプロパティを使用できます(実装した後、ほぼ同じことをした人を見つけました):
public class ListBoxItemEx
{
public static bool GetCanSelect(DependencyObject obj)
{
return (bool)obj.GetValue(CanSelectProperty);
}
public static void SetCanSelect(DependencyObject obj, bool value)
{
obj.SetValue(CanSelectProperty, value);
}
public static readonly DependencyProperty CanSelectProperty =
DependencyProperty.RegisterAttached("CanSelect", typeof(bool), typeof(ListBoxItemEx), new UIPropertyMetadata(true, OnCanSelectChanged));
private static void OnCanSelectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var item = sender as ListBoxItem;
if (item == null)
return;
if ((bool)args.NewValue)
{
item.Selected -= ListBoxItemSelected;
}
else
{
item.Selected += ListBoxItemSelected;
item.IsSelected = false;
}
}
private static void ListBoxItemSelected(object sender, RoutedEventArgs e)
{
var item = sender as ListBoxItem;
if (item == null)
return;
item.IsSelected = false;
}
}
xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow"
Width="525"
Height="350">
<Window.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="local:ListBoxItemEx.CanSelect" Value="{Binding CanSelect}"/>
</Style>
</Window.Resources>
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid Name="LayoutRoot">
<ListBox ItemsSource="{Binding Elements}" ItemContainerStyle="{DynamicResource ListBoxItemStyle}" SelectionMode="Multiple" />
</Grid>
ビューモデル:
public class ViewModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged values
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public List<Dummy> Elements { get; set; }
public ViewModel()
{
this.Elements = new List<Dummy>(){
new Dummy() { CanSelect =true, MyProperty = "Element1"},
new Dummy() { CanSelect =false, MyProperty = "Element2"},
new Dummy() { CanSelect =true, MyProperty = "Element3"},
new Dummy() { CanSelect =false, MyProperty = "Element4"},
new Dummy() { CanSelect =true, MyProperty = "Element5"},
new Dummy() { CanSelect =true, MyProperty = "Element6"},
new Dummy() { CanSelect =true, MyProperty = "Element7"},
new Dummy() { CanSelect =true, MyProperty = "Element8"},
new Dummy() { CanSelect =false, MyProperty = "Element9"},
};
}
}
public class Dummy
{
public bool CanSelect { get; set; }
public string MyProperty { get; set; }
public override string ToString()
{
return this.MyProperty;
}
}
このアプローチの唯一の注意点は、選択できない項目を選択しようとすると、ListBoxに単一の選択がある場合は現在選択されている項目の選択が解除され、ListBoxに拡張選択がある場合はすべての選択が解除されることです。