我有一个名为OnVisualChartRangeChanged的自定义事件从名为HistoricChartControl的UserControl中触发。
我在我的主应用程序中使用这样的控件:
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<viewModels:HistoricViewModel/>
</Window.DataContext>
<Grid>
<historicChart:HistoricChartControl >
<historicChart:HistoricChartControl
behaviours:ChartBehavior.OnVisualChartRangeChanged="VisualChartRangeChanged"/>
</historicChart:HistoricChartControl>
</Grid>
我希望通过VisualChartRangeChanged方法在视图中处理事件,而不是在ViewModel中处理事件。
我怎样才能修改我的代码呢?如果您可以发布特定代码,因为我是WPF工作方式的新手,将会很有帮助。
感谢。
答案 0 :(得分:1)
解决方案是使用命令。
由于它是UserControl,您可以操纵它来实现ICommandSource接口。
然后您的UserControl将能够将Command绑定到ViewModel。
一旦事件被触发,您只需调用将从ViewModel调用Execute()方法的命令。
对于WPF中的命令,我建议您阅读以下链接:
http://msdn.microsoft.com/en-us/library/ms752308(v=vs.110).aspx
在ViewModel中,您必须提供ICommand类型的属性。
编辑由于您无法操纵您的UserControl,您必须在XAML中附加命令。
交互性也是解决问题的另一种选择。看看这段代码:
xmlns:I="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<ListBox ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Interactivity是Microsoft Blend的第三方dll。
如果您在visual studio中有nuget,您将能够找到该dll。如果不是,则链接:http://www.nuget.org/packages/System.Windows.Interactivity.WPF/
答案 1 :(得分:0)
此答案已更改一次。
如果使用的行为是可重用的(您有其源),则只需将此行为的逻辑移至ViewModel级别即可。遵循这4个步骤,如果绑定和DataContext值正确,它应该有效。
System.Windows.Interactivity
和Microsoft.Expression.Interactions
的引用添加到您的项目中:在ViewModel中创建一个命令
//ViewModel:
public ICommand VisualChartRangeChangedCommand
{
get { return (ICommand)GetValue(VisualChartRangeChangedCommandProperty); }
set { SetValue(VisualChartRangeChangedCommandProperty, value); }
}
public static readonly DependencyProperty VisualChartRangeChangedCommandProperty =
DependencyProperty.Register("VisualChartRangeChangedCommand", typeof(ICommand), typeof(ViewModel), new UIPropertyMetadata(null));
//In ViewModel constructor:
VisualChartRangeChangedCommand = new ActionCommand(() => doStuff());
覆盖行为并向其添加命令功能
public class OnVisualChartRangeChangedWithCommand : OnVisualChartRangeChanged<HistoricChartControl>
{
//MyCommand Dependency Property
public ICommand MyCommand
{
get { return (ICommand)GetValue(MyCommandProperty); }
set { SetValue(MyCommandProperty, value); }
}
public static readonly DependencyProperty MyCommandProperty =
DependencyProperty.Register("MyCommand", typeof(ICommand), typeof(OnVisualChartRangeChangedWithCommand), new UIPropertyMetadata(null));
protected override void OnAttached()
{
//replace MouseEnter with other events related to OnVisualChartRangeChanged
AssociatedObject.MouseEnter += _eh;
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.MouseEnter -= _eh;
base.OnDetaching();
}
void _eh(object sender, MouseEventArgs e)
{
if (MyCommand != null)
MyCommand.Execute(null);
}
}
将ViewModel的Command
链接到覆盖Behavior
xmlns:I="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:B="clr-namespace:CoreProject.Behaviors;assembly=CoreProject"
<historicChart:HistoricChartControl>
<I:Interaction.Behaviors>
<B:OnVisualChartRangeChangedWithCommand MyCommand="{Binding VisualChartRangeChangedCommand}"/>
</I:Interaction.Behaviors>
</historicChart:HistoricChartControl>