zoukankan      html  css  js  c++  java
  • 基于WPF系统框架设计(9)-多值绑定之IMultiValueConverter

    应用场景

    我想把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="ImagesGreen.png" LargeIcon="ImagesGreenLarge.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层了。眨眼

  • 相关阅读:
    JS中的prototype
    Php5.3的lambda函数以及closure(闭包)
    JavaScript事件委托的技术原理
    css 里层元素撑不开外层元素
    扩展VirtualBox虚拟机磁盘容量
    easyUI 条件查询 跟分页数据展示写在了一起的
    (转)Hibernate中关于多表连接查询hql 和 sql 返回值集合中对象问题
    有想去北京工作的的想法了
    第一次写oracle SQL 两个表链接查询
    第三天 SQL小记
  • 原文地址:https://www.cnblogs.com/aganqin/p/3277075.html
Copyright © 2011-2022 走看看