好的,我正在使用这些自定义控件。不过不用担心这个问题,这个问题与他们的工作无关。
有问题的控件是一个网格(就像常规网格一样),它带有一个BeginInsert函数,它是向列表添加新项目的捷径。
现在我想要的是在我的视图模型中访问该方法。目前我确实有这个,但它通过我的XAML代码,我不想要 - 我希望它直接从XAML到视图模型。
目前的情况如下:
((UserViewModel)Resources["usersViewModel"]).HydUsersGridBeginInsert = () => this.GridViewData.BeginInsert();
此代码位于XAML代码后面。 HydUsersGridBeginInsert的类型为Action,位于视图模型中。 GridViewData是网格的名称。
那么如何从我的代码中直接进入我的视图模型呢?
感谢。
答案 0 :(得分:1)
使用event to command with parameters。
<Button Content="Add">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding AddClickCommand, Mode=OneWay}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
这里命名空间“i”指的是xmlns:i =“clr-namespace:System.Windows.Interactivity; assembly = System.Windows.Interactivity” 和
的xmlns:CMD = “CLR-名称空间:GalaSoft.MvvmLight.Command;装配= GalaSoft.MvvmLight.Extras.SL4”
这是galasoft MVVM轻工具包(谷歌下载)
在viewModel中添加类似的代码,如
public ICommand AddClickCommand { get; set; }
AddClickCommand = new RelayCommand<string>((e) =>
{
this.BeginInsert();
});
我以为你会从我的回答开始。
我想说服你的是
<your:YourGrid x:Name="yourGrid">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding GridLoadedCommand, Mode=OneWay}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</your:YourGrid>
您需要做的只是在LoadedCommand中。
YourGrid grid ;
public ICommand GridLoadedCommand { get; set; }
GridLoadedCommand = new RelayCommand<RoutedEventHandler>((s, e) =>
{
grid = (YourGrid) s;
});
public ICommand AddClickCommand { get; set; }
AddClickCommand = new RelayCommand<string>((e) =>
{
grid.BeginInsert();
});
Now what you say about this.
答案 1 :(得分:1)
我相信你想要的是能够在你的ViewModel中调用网格上的BeginEdit吗?有几种方法可以做到这一点:
1)您可以使用Messaging,就像MVVM-Light框架中的那样。在您的代码中,您将订阅一个事件BeginEdit,并在ViewModel中发布BeginEdit事件。
2)您可以创建行为,here是一个类似的示例,其中TreeView上的节点通过使用行为进行扩展。
因此,在该示例中,您可以设置一个变量IsBeginEdit,并且该行为将触发,在GridView上调用BeginEdit。 source MiscView / MiscViewModel
行为:
在我列出的示例源中,我正在使用Caliburn Micro并命名按钮元素x:Name =“BeginEdit”CM将自动将其绑定到我的BeginEdit方法。如果你正在使用Mvvm-Light,你可以使用EventToCommand。
<Button Content="BeginEdit">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding BeginEdit, Mode=OneWay}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
[Description("BeginEdit")]
public class BeginEditBehavior : TargetedTriggerAction<RadGridView>
{
private RadGridView _radGridView;
protected override void OnAttached()
{
base.OnAttached();
_radGridView = (RadGridView) (AssociatedObject);
}
protected override void Invoke(object parameter)
{
_radGridView.BeginEdit();
}
}
View:
<telerik:RadGridView ItemsSource="{Binding MyItems, Mode=TwoWay}">
<i:Interaction.Triggers>
<ei:PropertyChangedTrigger Binding="{Binding IsBeginEdit, Mode=TwoWay}">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding IsBeginEdit}"
RightOperand="True" />
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<framework:BeginEditBehavior />
</ei:PropertyChangedTrigger>
</i:Interaction.Triggers>
</telerik:RadGridView>
视图模型:
private bool _isBeginEdit;
public bool IsBeginEdit
{
get { return _isBeginEdit; }
set
{
_isBeginEdit = value;
NotifyOfPropertyChange(() => IsBeginEdit);
}
}
public void BeginEdit()
{
IsBeginEdit = true;
}
3)可能不是最好的方法,您可以在ViewModel中存储对View的引用。作为示例,Caliburn Micro为您提供了一种从ViewModel中访问View GetView()的方法,然后您可以获得对网格的引用并调用BeginEdit()。
我喜欢选项2但是1也适用。