Silverlight MVVM 贴近实战(六)

Silverlight MVVM 贴近实战(六),第1张

概述扯面工程师,配菜工程师,门迎工程师,当今世界工程师可真多啊。 今天我们把系统参数管理模块翻译成Silverlight项目。首先请看两张图 再看看翻译好的图 其实我们看到了第二张图用到了treeView,Popup,这节主要讲的还是MVVM,不过和以往有所不同。先看看前台代码 <controls:ChildWindow x:Class="MISInfoManage.CodeMan

扯面工程师,配菜工程师,门迎工程师,当今世界工程师可真多啊。

今天我们把系统参数管理模块翻译成Silverlight项目。首先请看两张图

再看看翻译好的图

其实我们看到了第二张图用到了treeVIEw,Popup,这节主要讲的还是MVVM,不过和以往有所不同。先看看前台代码

  <controls:ChilDWindow x:Class="MISInfoManage.CodeManageVIEw"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:d="http://schemas.microsoft.com/Expression/blend/2008"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"         xmlns:toolkit="clr-namespace:System.windows.Controls;assembly=System.windows.Controls"         xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"         xmlns:resource="clr-namespace:MISInfoManage.Resources"         xmlns:controls="clr-namespace:System.windows.Controls;assembly=System.windows.Controls"         xmlns:Primitives="clr-namespace:System.windows.Controls.Primitives;assembly=System.windows"         mc:Ignorable="d" WIDth="700" Height="400" FontSize="13"         Title="系统参数管理">         <controls:ChilDWindow.Resources>             <resource:CodeManageResource x:Key="CodeManageResource"/>             <Style x:Key="ColumnheaderStyle" targettype="sdk:DataGrIDColumnheader">                 <Setter Property="Height" Value="25"></Setter>             </Style>         </controls:ChilDWindow.Resources>         <GrID x:name="LayoutRoot" Background="White">             <GrID.RowDeFinitions>                 <RowDeFinition Height="*"></RowDeFinition>             </GrID.RowDeFinitions>             <GrID.ColumnDeFinitions>                 <ColumnDeFinition WIDth="auto"></ColumnDeFinition>                 <ColumnDeFinition WIDth="*"></ColumnDeFinition>                 <ColumnDeFinition WIDth="0"></ColumnDeFinition>             </GrID.ColumnDeFinitions>             <border borderBrush="AliceBlue" WIDth="150" GrID.Row="0" GrID.Column="0" borderThickness="1" CornerRadius="2" margin="0,10,0">                 <toolkit:TreeVIEw x:name="treeVIEwCode"></toolkit:TreeVIEw>             </border>             <sdk:DataGrID GrID.Row="0" GrID.Column="1"                               borderBrush="Black" borderThickness="1"                               IsReadonly="True" x:name="dgCodeList"                               autoGenerateColumns="False"                               AlternatingRowBackground="Gray"                               CanUserReorderColumns="True"                               VerticalScrollbarVisibility="auto"                               HorizontalScrollbarVisibility="auto"                                 SelectionMode="Single"                               SelectedItem="{Binding CodeEntity,Mode=TwoWay}"                               ItemsSource="{Binding CodeList,Mode=OneWay}"                               CanUserSortColumns="True">                 <sdk:DataGrID.Columns>                     <sdk:DataGrIDTemplateColumn header="选择">                         <sdk:DataGrIDTemplateColumn.CellTemplate>                             <DataTemplate>                                 <CheckBox HorizontalAlignment="Center"></CheckBox>                             </DataTemplate>                         </sdk:DataGrIDTemplateColumn.CellTemplate>                     </sdk:DataGrIDTemplateColumn>                     <sdk:DataGrIDTextColumn Binding="{Binding data,Mode=OneWay}" headerStyle="{StaticResource ColumnheaderStyle}" header="数据值"/>                     <sdk:DataGrIDTextColumn Binding="{Binding ename,Mode=OneWay}" headerStyle="{StaticResource ColumnheaderStyle}" header="英文代码"/>                     <sdk:DataGrIDTextColumn Binding="{Binding cname,Mode=OneWay}" headerStyle="{StaticResource ColumnheaderStyle}" header="中文代码"/>                     <sdk:DataGrIDTextColumn Binding="{Binding display_content,Mode=OneWay}" headerStyle="{StaticResource ColumnheaderStyle}" header="显示值"/>                     <sdk:DataGrIDTemplateColumn header=" *** 作">                         <sdk:DataGrIDTemplateColumn.CellTemplate>                             <DataTemplate>                                 <StackPanel>                                     <StackPanel.Resources>                                         <Style x:Key="buttonStyle" targettype="button">                                             <Setter Property="Template">                                                 <Setter.Value>                                                     <ControlTemplate targettype="button">                                                         <border CornerRadius="2" borderThickness="1" borderBrush="Red">                                                             <StackPanel OrIEntation="Horizontal" Background="Turquoise">                                                                 <StackPanel.Effect>                                                                     <DropShadowEffect color="Black" Direction="270" ShadowDepth="5"                                                                           BlurRadius="5" Opacity="0.5">                                                                     </DropShadowEffect>                                                                 </StackPanel.Effect>                                                                 <Image Source="/MISInfoManage;component/Images/drag.png" Height="25" WIDth="60"/>                                                                 <TextBlock Text="修改" Foreground="brown" FontWeight="Bold"></TextBlock>                                                             </StackPanel>                                                         </border>                                                     </ControlTemplate>                                                 </Setter.Value>                                             </Setter>                                         </Style>                                     </StackPanel.Resources>                                     <button Content="button1"  Style="{StaticResource buttonStyle}"/>                                 </StackPanel>                             </DataTemplate>                         </sdk:DataGrIDTemplateColumn.CellTemplate>                     </sdk:DataGrIDTemplateColumn>                 </sdk:DataGrID.Columns>             </sdk:DataGrID>             <Primitives:Popup x:name="CodeInfoPop" GrID.Row="0" GrID.Column="2">                 <StackPanel WIDth="200">                     <StackPanel.Style>                         <Style targettype="StackPanel">                             <Setter Property="Background" Value="brown"></Setter>                         </Style>                     </StackPanel.Style>                     <StackPanel.Effect>                         <DropShadowEffect                         color="Black" Direction="300" ShadowDepth="10" BlurRadius="5" Opacity="0.6">                         </DropShadowEffect>                     </StackPanel.Effect>                     <StackPanel OrIEntation="Horizontal">                         <TextBlock Text="{Binding Tb_Ename,Source={StaticResource CodeManageResource}}"/>                         <TextBlock Text="{Binding CodeEntity.ename}" margin="5,0"/>                     </StackPanel>                     <StackPanel OrIEntation="Horizontal">                         <TextBlock Text="{Binding Tb_CNm,Source={StaticResource CodeManageResource}}"/>                         <TextBlock Text="{Binding CodeEntity.cname}" margin="5,0"/>                     </StackPanel>                     <StackPanel OrIEntation="Horizontal">                         <TextBlock Text="{Binding Tb_display,Source={StaticResource CodeManageResource}}"/>                         <TextBlock Text="{Binding CodeEntity.display_content}" margin="5,0"/>                     </StackPanel>                 </StackPanel>             </Primitives:Popup>         </GrID>     </controls:ChilDWindow>   

最普遍的布局方式GrID+StackPanel。记得上次好像我在写博客的时候,给每个控件都设置了FontSize,其实这个是没有必要的,只需要在controls:ChilDWindow节点中设置,那么整个页面的控件的FontSize都起作用。再往下看,有这样的一些节点

<Style x:Key="buttonStyle" targettype="button">...</Style>里面有这么一段代码

  <ControlTemplate targettype="button">                                                         <border CornerRadius="2" borderThickness="1" borderBrush="Red">                                                             <StackPanel OrIEntation="Horizontal" Background="Turquoise">                                                                 <StackPanel.Effect>                                                                     <DropShadowEffect color="Black" Direction="270" ShadowDepth="5"                                                                           BlurRadius="5" Opacity="0.5">                                                                     </DropShadowEffect>                                                                 </StackPanel.Effect>                                                                 <Image Source="/MISInfoManage;component/Images/drag.png" Height="25" WIDth="60"/>                                                                 <TextBlock Text="修改" Foreground="brown" FontWeight="Bold"></TextBlock>                                                             </StackPanel>                                                         </border>                                                     </ControlTemplate>   

这个是定义一个button的控件模版。在这里我们给StackPanel定义了一个特效DropShadowEffect ,一个阴影效果。在这个模板中我放置了一个图片和一个文本,大家看看上面的图就知道了。整个一按钮变成如此摸样,所以在我们做开发的时候,可以通过设置ControlTemplate来定制我们按钮或者其他控件的模版。在按钮中,我们只需要设置Style="{StaticResource buttonStyle}"即可。再往下走,有这么一段代码

<Primitives:Popup x:name="CodeInfoPop" GrID.Row="0" GrID.Column="2">这个节点正是定义我们的Popup,当DataGrID的SelectionChanged触发时,d出Popup。注意Popup这里需要引用System.windows.Controls.Primitives。好了前台没什么,就这么些。我们看看页面后台,代码如下

  namespace MISInfoManage      {          public partial class CodeManageVIEw : ChilDWindow          {              CodeManageModel codeManage;              public CodeManageVIEw()              {                  InitializeComponent();                  codeManage = new CodeManageModel(this);                  this.LayoutRoot.DataContext = codeManage;              }          }        

我勒了个去,怎么就这么点代码,我告诉你,就这么点代码。我们这次使用了Behavior,那么就不会出现页面后台事件。看看viewmodel到底都干了些什么。

  namespace MISInfoManage.viewmodels      {          public class CodeManageModel : INotifyPropertyChanged          {              public ChilDWindow userControl;              CodeManageServiceClIEnt clIEnt;              SelectionChangedBehavior mouseRightbuttonBrhavior;              public CodeManageModel()              {                  clIEnt = new CodeManageServiceClIEnt();                  this.GetCodesList((obj, args) =>                  {                      this.CodesList = args.Result;                      this.BuildTree();                  });              }                   public CodeManageModel(ChilDWindow userControl)                  : this()              {                  this.userControl = userControl;                  this.mouseRightbuttonBrhavior = new SelectionChangedBehavior(this);                  mouseRightbuttonBrhavior.Attach((userControl as CodeManageVIEw).dgCodeList);                  this.SetContextMenu();              }                   private List<Codes> codesList;              public List<Codes> CodesList              {                  get                 {                      return codesList;                  }                  set                 {                      codesList = value;                      NotifyPropertyChange("CodesList");                  }              }                   private List<Codes> codeList;              public List<Codes> CodeList              {                  get                 {                      return codeList;                  }                  set                 {                      codeList = value;                      NotifyPropertyChange("CodeList");                  }              }                   private Codes codeEntity;              public Codes CodeEntity              {                  set                 {                      codeEntity = value;                      NotifyPropertyChange("CodeEntity");                  }                  get                 {                      return codeEntity;                  }              }                   public voID GetCodesList(EventHandler<GetCodeListCompletedEventArgs> handler)              {                  clIEnt.GetCodeListCompleted += handler;                  clIEnt.GetCodeListAsync();              }                   public voID GetCodeListByCondition(string ename, EventHandler<GetCodeListByConditionCompletedEventArgs> handler)              {                  clIEnt.GetCodeListByConditionCompleted += handler;                  clIEnt.GetCodeListByConditionAsync(ename);              }                   public voID BuildTree()              {                  TreeVIEwItem mainitem = new TreeVIEwItem();                  mainitem.header = "系统参数";                  mainitem.IsExpanded = true;                  List<Codes> codeList = null;                  if (this.CodesList != null && this.CodesList.Count > 0)                  {                      codeList = this.CodesList.distinct<Codes>(new EqualityCompare()).ToList();                      codeList.ForEach(c =>                      {                          TreeVIEwItem treeVIEwItem = new TreeVIEwItem();                          StackPanel stackPanel = new StackPanel();                          stackPanel.OrIEntation = OrIEntation.Horizontal;                          TextBlock textBlock = new TextBlock();                          textBlock.Text = c.cname;                          textBlock.Tag = c.ename;                          textBlock.MouseleftbuttonDown += this.LoadCodeByID;                          Image image = new Image();                          image.WIDth = 12;                          image.Height = 12;                          image.margin = new Thickness(0, 0, 5, 0);                          image.source = new BitmAPImage(new Uri("../Images/windows.jpg", UriKind.relative));                          stackPanel.Children.Add(image);                          stackPanel.Children.Add(textBlock);                          treeVIEwItem.header = stackPanel;                          mainitem.Items.Add(treeVIEwItem);                      });                      (this.userControl as CodeManageVIEw).treeVIEwCode.Items.Add(mainitem);                  }              }                   private voID LoadCodeByID(object sender, MousebuttonEventArgs e)              {                  TextBlock textBlock = sender as TextBlock;                  string ename = textBlock.Tag.ToString();                  this.GetCodeListByCondition(ename, (obj, args) =>                  {                      this.CodeList = args.Result;                  });              }                   private voID SetContextMenu()              {                  ContextMenu contextMenu = new ContextMenu();                  MenuItem menuItem = new MenuItem();                  menuItem.Tag = "Modify";                  TextBlock textBlock = new TextBlock();                  textBlock.Text = "修改";                  menuItem.header = textBlock;                  contextMenu.Items.Add(menuItem);                  menuItem = new MenuItem();                  textBlock = new TextBlock();                  textBlock.Text = "添加";                  menuItem.Tag = "Add";                  menuItem.header = textBlock;                  contextMenu.Items.Add(menuItem);                  menuItem = new MenuItem();                  textBlock = new TextBlock();                  textBlock.Text = "关闭";                  menuItem.Tag = "Close";                  menuItem.header = textBlock;                  menuItem.Click += delegate(object sender, RoutedEventArgs e)                  {                      (userControl as CodeManageVIEw).Close();                  };                  contextMenu.Items.Add(menuItem);                  ContextMenuService.SetContextMenu((this.userControl as CodeManageVIEw).dgCodeList, contextMenu);              }                   public event PropertyChangedEventHandler PropertyChanged;              private voID NotifyPropertyChange(string property)              {                  if (PropertyChanged != null)                  {                      PropertyChanged(thisnew PropertyChangedEventArgs(property));                  }              }          }               public class EqualityCompare : IEqualityComparer<Codes>          {              public bool Equals(Codes code1, Codes code2)              {                  return code1.ename.Equals(code2.ename);              }                   public int GetHashCode(Codes code)              {                  return code.ename.GetHashCode();              }          }        

首先进入构造函数,初始化我们的TreeVIEw,初始化TreeVIEw的时候有这么个代码codeList = this.CodesList.distinct<Codes>(new EqualityCompare()).ToList();去除List<T>重复。我们知道对象的值都一样,不代表对象一样。所以我们需要实现IEqualityComparer<T>接口,Equals方法确定你要distinct的规则,在这里就是Ename不相等。GetHashCode必须返回Ename的HashCode。再往下走,这么一段代码

  this.mouseRightbuttonBrhavior = new SelectionChangedBehavior(this);                  mouseRightbuttonBrhavior.Attach((userControl as CodeManageVIEw).dgCodeList);   

在这里使用到了Behavior,我们为DataGrID定义了一个行为,我们来看看这个行为

  namespace MISInfoManage.Behavior      {          public class SelectionChangedBehavior : Behavior<DataGrID>          {              CodeManageModel _codeManageModel;              public SelectionChangedBehavior():base()              {}              public SelectionChangedBehavior(CodeManageModel codeManageModel)                  : this()              {                  _codeManageModel = codeManageModel;              }              protected overrIDe voID OnAttached()              {                  base.OnAttached();                  this.Associatedobject.SelectionChanged += Associatedobject_SelectionChanged;                  this.Associatedobject.MouseMove += Associatedobject_MouseMove;              }                   protected overrIDe voID OnDetaching()              {                  base.OnDetaching();                  this.Associatedobject.SelectionChanged -= Associatedobject_SelectionChanged;                  this.Associatedobject.MouseMove -= Associatedobject_MouseMove;              }                   private voID Associatedobject_SelectionChanged(object sender, SelectionChangedEventArgs e)              {                  if (_codeManageModel.CodeEntity != null)                  {                      Popup popup = (this._codeManageModel.userControl as CodeManageVIEw).CodeInfoPop;                      popup.HorizontalOffset = 20;                      popup.VerticalOffset = 70;                      popup.IsOpen = true;                  }              }                   private voID Associatedobject_MouseMove(object sender,MouseEventArgs e)              {                  Popup popup = (this._codeManageModel.userControl as CodeManageVIEw).CodeInfoPop;                  popup.IsOpen = false;              }          }        

在这里我只说一个基类,其他的就不往出贴了,大家自己看

  namespace System.windows.Interactivity      {          // Summary:          //     Encapsulates state information and zero or more ICommands into an attachable          //     object.          //          // Type parameters:          //   T:          //     The type the System.windows.Interactivity.Behavior<T> can be attached to.          //          // Remarks:          //     Behavior is the base class for provIDing attachable state and commands to          //     an object.  The types the Behavior can be attached to can be controlled by          //     the generic parameter.  OverrIDe OnAttached() and OnDetaching() methods to          //     hook and unhook any necessary handlers from the Associatedobject.          public abstract class Behavior<T> : Behavior where T : System.windows.DependencyObject          {              // Summary:              //     Initializes a new instance of the System.windows.Interactivity.Behavior<T>              //     class.              protected Behavior();                   // Summary:              //     Gets the object to which this System.windows.Interactivity.Behavior<T> is              //     attached.              protected T Associatedobject { get; }          }        

这里的的Associatedobject就是泛型T,并且它是System.windows.DependencyObject类型的。Behavior类是个抽象类,具有Attach,Detach,OnAttached,OnDetaching方法。OnAttached在Attach方法调用以后生效。所以这段代码就实现了DataGrID的SelectionChanged和MouseMove事件,在SelectionChanged以后d出Popup,MouseMove以后隐藏Popup。这种方式是不是很有效的实现了页面UI和逻辑的分离。再往下走,有个SetContextMenu方法,正是给DataGrID附加一个d出菜单。在菜单构造好以后,需要调用ContextMenuService.SetContextMenu((this.userControl as CodeManageVIEw).dgCodeList,contextMenu);,第一个参数是一个DependencyObject类型的对象,第二个是ContextMenu对象。类似于这样的内置对象还有FocusManager,它的方法FocusManager.GetFocusedElement()可以直接找到页面获得焦点的元素。我们来看看这个菜单的效果,

当我们点击关闭的时候,将会关闭该页面。OK,今天就讲到这里,时间也不早了,洗洗睡。

总结

以上是内存溢出为你收集整理的Silverlight MVVM 贴近实战(六)全部内容,希望文章能够帮你解决Silverlight MVVM 贴近实战(六)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1066460.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存