应用场景

我想把View层的一个布局控件和功能按钮传到ViewModel层,达到动态变更布局,同时灵活获取功能按钮的属性,让View和ViewModel完全分离,而不受View层影响。

最后我想到使用IMultiValueConverter实现多参传入ViewModel层来解决,不知道还有没有更好的办法?

基本原理:要将值转换器与 MultiBinding 关联,请创建一个实现 IMultiValueConverter 接口的类,然后实现 Convert 和 ConvertBack 方法。
集合中的各个绑定可以具有自己的值转换器。

使用 MultiBinding,您可以将绑定目标属性绑定到源属性列表,然后应用逻辑以使用给定的输入生成值。

实现步骤

    添加继承IMultiValueConverter接口的类并实现接口

    注意:返回的values一定要转为数组列表values.ToArray()

参考如下代码

using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace TLAgent.SecurityManager.WPF.MultiBindings
{
  public class DataConverter : IMultiValueConverter
  {
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
        return values.ToArray() ;
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
      object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
  }
}

在XAML中进行多参绑定

<Fluent:Button Header="添加用户" Icon="Images\Green.png" LargeIcon="Images\GreenLarge.png" x:Name="BtnAddUser" Command="{Binding AddUserCommand}">
                        <Fluent:Button.CommandParameter>
                            <MultiBinding Converter="{ StaticResource ResourceKey=dataConverter}" Mode="TwoWay">
                                <MultiBinding.Bindings>
                                    <Binding ElementName="BtnAddUser"/>
                                    <Binding ElementName="dockManager "/>
                                </MultiBinding.Bindings>
                            </MultiBinding>
                        </Fluent:Button.CommandParameter>
                        
                    </Fluent:Button>
<Window.Resources>
        <local:DataConverter x:Key="dataConverter"/>
</Window.Resources>

ViewModel中进行命令和方法绑定

注意:DelegateCommand<object[]>的参数是要支持对象数组。

using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
using Xceed.Wpf.AvalonDock;
using Xceed.Wpf.AvalonDock.Layout;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;
using UserControl = System.Windows.Controls.UserControl;

namespace TLAgent.SecurityManager.WPF.ViewModels
{
    public class MainWindowViewModel : NotificationObject
    {
        public ICommand ExitSystemCommand { get; set; }

        public ICommand AddUserCommand { get; set; }

        public ICommand OpenHelpCommand { get; set; }

        public MainWindowViewModel()
        {
            ExitSystemCommand = new DelegateCommand(this.OnExit);
            OpenHelpCommand = new DelegateCommand(this.OnOpenSupport);
            AddUserCommand = new DelegateCommand<object[]>(this.AddUser);
        }


        private void CreateTab(DockingManager dockManager, string tabName, UserControl control)
        {
            var firstDocumentPane = dockManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            if (firstDocumentPane != null)
            {
                LayoutDocument doc2 = new LayoutDocument();
                doc2.Title = tabName;
                doc2.Content = control;
                doc2.IsActive = true;
                firstDocumentPane.Children.Add(doc2);
            }
        }

        private void OnExit()
        {
            MessageBoxResult result = MessageBox.Show("确定要退出系统吗?", "确认消息", MessageBoxButton.OKCancel, MessageBoxImage.Question);
            if (result == MessageBoxResult.OK)
            {
                Application.Current.Shutdown();
            }
        }

        private void OnOpenSupport()
        {
            MessageBox.Show("帮助窗口!");
        }
        
       private void AddUser(object[] objParam)
       {
            if (objParam.Length == 2)
            {
                Fluent.Button button = (Fluent.Button)objParam[0];
                DockingManager dockingManager = (DockingManager)objParam[1];
                UserControl control;
                control = new UserControl1();

                CreateTab(dockingManager, button.Header.ToString(), control);
            }
      }
    }
}

控件绑定

这样就可以在方法AddUer的参数中取得View层绑定的两个控件:

<MultiBinding.Bindings>
     <Binding ElementName="BtnAddUser"/>
     <Binding ElementName="dockManager "/>
</MultiBinding.Bindings>

这样基本就实现了从View层传多个对象到ViewModel层了。眨眼

posted on 2013-08-23 11:09  aganqin  阅读(3667)  评论(0编辑  收藏  举报