爲了達到這個目的,您可以使用附加的行爲,並且您會發現它是一個乾淨的MVVM策略。
創建一個WPF應用程序,並添加此XAML ...
<Grid>
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="bindTreeViewExpand:Behaviours.ExpandingBehaviour" Value="{Binding ExpandingCommand}"/>
</Style>
</TreeView.Resources>
<TreeViewItem Header="this" >
<TreeViewItem Header="1"/>
<TreeViewItem Header="2"><TreeViewItem Header="Nested"></TreeViewItem></TreeViewItem>
<TreeViewItem Header="2"/>
<TreeViewItem Header="2"/>
<TreeViewItem Header="2"/>
</TreeViewItem>
<TreeViewItem Header="that" >
<TreeViewItem Header="1"/>
<TreeViewItem Header="2"/>
<TreeViewItem Header="2"/>
<TreeViewItem Header="2"/>
<TreeViewItem Header="2"/>
</TreeViewItem>
</TreeView>
</Grid>
然後創建一個這樣的視圖模型...
public class ViewModel : INotifyPropertyChanged
{
public ICommand ExpandingCommand { get; set; }
public ViewModel()
{
ExpandingCommand = new RelayCommand(ExecuteExpandingCommand, CanExecuteExpandingCommand);
}
private void ExecuteExpandingCommand(object obj)
{
Console.WriteLine(@"Expanded");
}
private bool CanExecuteExpandingCommand(object obj)
{
return true;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
我採用中繼的命令,但你可以使用可以交換委託命令。繼電器命令的源是在http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
然後創建一個單獨的類,看起來像這樣...
public static class Behaviours
{
#region ExpandingBehaviour (Attached DependencyProperty)
public static readonly DependencyProperty ExpandingBehaviourProperty =
DependencyProperty.RegisterAttached("ExpandingBehaviour", typeof(ICommand), typeof(Behaviours),
new PropertyMetadata(OnExpandingBehaviourChanged));
public static void SetExpandingBehaviour(DependencyObject o, ICommand value)
{
o.SetValue(ExpandingBehaviourProperty, value);
}
public static ICommand GetExpandingBehaviour(DependencyObject o)
{
return (ICommand) o.GetValue(ExpandingBehaviourProperty);
}
private static void OnExpandingBehaviourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TreeViewItem tvi = d as TreeViewItem;
if (tvi != null)
{
ICommand ic = e.NewValue as ICommand;
if (ic != null)
{
tvi.Expanded += (s, a) =>
{
if (ic.CanExecute(a))
{
ic.Execute(a);
}
a.Handled = true;
};
}
}
}
#endregion
}
然後導入這個類的名稱空間爲XAML中......
xmlns:bindTreeViewExpand =「clr-namespace:BindTreeViewExpand」(你的名字空間將會不同!)
resharper會爲你做這個,或者給你一個intellesense提示。
最後連接視圖模型。使用快速和骯髒的方法是這樣的...
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
然後,在名稱空間解決,接線是否正確,它就會開始工作。將您的調試器固定在Execute方法中,並觀察您得到一個RoutedEvent參數。你可以解析這個來獲得哪個Tree view項目被展開。
此解決方案的關鍵方面是在STYLE中指定的行爲!所以它應用於每個TreeViewItem。沒有任何代碼(除了行爲)。
上面列出的行爲標記事件處理。根據你以後的行爲,你可能希望改變它。
是的,請一定要發表一個答案。我沒有使用棱鏡,但我會看看我是否可以得到它的工作。 – Gigi
好吧,我會發佈一個一步一步的答案,我們會看看它是否有用。 –
注意:由於該命令綁定到某個行爲,因此您不應該內聯聲明「 –