这就是MVVM警察! ;)
Xaml:改用 ICommand 和 System.Windows.Interactivity 的绑定,例如 galasoft mvvm light。我没有测试下面的代码,我只是用notepad++编写的。哎呀,我现在在这里看到一件事,您正在数据模板和列表框项中执行此操作...您的 TextBlock 将在 LI 而不是 VM 上查找命令,因此您需要在这里进行时髦的绑定。检查它是否有效,但您希望单击事件在虚拟机的数据上下文上执行,而不是在列表框项上执行,因此必须稍微更改绑定(假期...=))
列表框中的项目包装在 ListBoxItems 中,并且数据上下文设置为 LI 应该呈现的内容,即列表中的项目。
您可能想要更改下面的 KeyUp 绑定
<command:EventToCommand Command="{Binding KeyUpCommand}" PassEventArgsToCommand="True"/>
To:
<command:EventToCommand Command="{Binding Path=DataContext.KeyUpCommandCommand, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}" PassEventArgsToCommand="True"/>
确保将 UserControl 替换为您的控件/页面/自定义 ctrl/窗口的名称。
...
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:local="clr-namespace:YOURNAMSPACE"
...
<UserControl.DataContext>
<local:ViewModelListStuff/>
</UserControl.DataContext>
<Grid>
<ItemsControl ItemsSource="{Binding Source={StaticResource cvsRoutes}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Header="{Binding Name}" MinHeight="50">
<ListBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<command:EventToCommand Command="{Binding PreviewMouseLeftButtonDownCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBlock Text="Something" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyUp">
<command:EventToCommand Command="{Binding KeyUpCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock Text="Something" />
<TextBlock Text="Something" />
<TextBlock Text="Something" />
<TextBlock Text="Something" />
</ListBox>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
现在您将需要一个视图模型,将其设置为数据上下文。这是一个带有简单基类的示例(很好地扩展galasoft提供的ViewModelBase来添加功能。
VM基类(简化):
public class SomeBaseClass : INotifyPropertyChanged
{
// Other common functionality goes here..
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]// Commment out if your don't have R#
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
VM:
public class ViewModelListStuff : SomeBaseClass
{
private string name;
public ICommand PreviewMouseLeftButtonDownCommand { get; set; }
public ICommand KeyUpCommand { get; set; }
public String Name
{
get { return name; }
set
{
if (value == name) return;
name = value;
OnPropertyChanged();
}
}
// I would have exposed your cvsSomething here as a property instead, whatever it is.
public ViewModelListStuff()
{
InitStuff();
}
public void InitStuff()
{
PreviewMouseLeftButtonDownCommand = new RelayCommand<MouseButtonEventArgs>(PreviewMouseLeftButtonDown);
KeyUpCommandnCommand = new RelayCommand<KeyEventArgs>(KeyUp);
}
private void KeyUp(KeyEventArgs e)
{
// Do your stuff here...
}
private void PreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
// Do your stuff heere
}
}
希望能帮助到你!在命令调用的方法中创建一个断点,并观察命令方法的输出和堆栈跟踪。
Cheers
Stian