将Silverlight控件功能绑定到我的视图模型

时间:2011-12-09 10:53:58

标签: silverlight c#-4.0 silverlight-4.0

好的,我正在使用这些自定义控件。不过不用担心这个问题,这个问题与他们的工作无关。

有问题的控件是一个网格(就像常规网格一样),它带有一个BeginInsert函数,它是向列表添加新项目的捷径。

现在我想要的是在我的视图模型中访问该方法。目前我确实有这个,但它通过我的XAML代码,我不想要 - 我希望它直接从XAML到视图模型。

目前的情况如下:

((UserViewModel)Resources["usersViewModel"]).HydUsersGridBeginInsert = () => this.GridViewData.BeginInsert();

此代码位于XAML代码后面。 HydUsersGridBeginInsert的类型为Action,位于视图模型中。 GridViewData是网格的名称。

那么如何从我的代码中直接进入我的视图模型呢?

感谢。

2 个答案:

答案 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也适用。