前一篇说了一个较为复杂的方案,以解决向外代理绑定的问题,上一篇的方案在WPF中是不适用的。现在可以提一个较为通用的方案,可以为WPF及SL共同解决的。方案很简单。
1 <DataGrid ItemsSource="{Binding Path=AccountStore}"> 2 <DataGrid.Columns> 3 <DataGridTextColumn Header="账户名称" Binding="{Binding Path=AccountName}"/> 4 <DataGridTemplateColumn Header="相关操作"> 5 <DataGridTemplateColumn.CellTemplate> 6 <DataTemplate> 7 <Button Command={Binding Path=Edit}>编辑</Button> 8 </DataTemplate> 9 </DataGridTemplateColumn.CellTemplate> 10 </DataGridTemplateColumn> 11 </DataGrid.Columns> 12 </DataGrid>
显然这样,Edit的Command是属于AccountStore的,这样位置就乱了。这里我们只需要设定它的RelativeSource就可以了。我们可以改成这样
<UserControl x:Class="KnetSmartBox.ReportModule.Views.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <DataGrid ItemsSource="{Binding Path=AccountStore}"> <DataGrid.Columns> <DataGridTextColumn Header="账户名称" Binding="{Binding Path=AccountName}"/> <DataGridTemplateColumn Header="相关操作"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Command="{Binding Path=DataContext.Edit,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">编辑</Button> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid> </UserControl>
注意标黄的一段,自己理解一下。
这个属性可以让控件找寻DataContext,这里常用的有两种方式,这里用的是AncestorType,也就是根据类型找,还可以根据级别找,就是AncestorLevel。
目前这个问题只针对Silverlight得到了解决。原因很简单,因为DataGrid一般在使用的时候都设置了ItemSource,这样里面的Command当然只会响应ItemSource里面的Command方法。这样一来,就需要在页面载入的时候,把页面的ViewModel保存下来,这样就暂时叫DataContext的代理吧,在使用的时候,调这个代理中的Command就可以了。代理可以单独地写成一个类。写法如下:
1 using System;
2 using System.Windows;
3 using System.Windows.Controls;
4 using System.Windows.Data;
5
6 namespace Common
7 {
8 public class DataContextProxy : FrameworkElement
9 {
10 public DataContextProxy()
11 {
12 this.Loaded += (s, e) =>
13 {
14 Binding binding = new Binding();
15 if (!string.IsNullOrEmpty(BindingPropertyName))
16 {
17 binding.Path = new PropertyPath(BindingPropertyName);
18 }
19 binding.Source = this.DataContext;
20 binding.Mode = BindingMode;
21 this.SetBinding(DataContextProxy.DataSourceProperty, binding);
22 };
23 }
24
25 #region 依赖项属性
26 public Object DataSource
27 {
28 get { return (Object)GetValue(DataSourceProperty); }
29 set { SetValue(DataSourceProperty, value); }
30 }
31
32 public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);
33
34 public string BindingPropertyName { get; set; }
35 public BindingMode BindingMode { get; set; }
36 #endregion
37 }
38 }
使用的时候需要在Xaml中添加对这个类所在的命名空间进行引用,例如:
xmlns:common="clr-namespace:GoldStock.Common;assembly=GoldStock.Common"
然后在Xaml中实例化这个代理类,例如:
<UserControl>
<UserControl.Resources>
<common:DataContextProxy x:Key="DataContextProxy"/>
</UserControl.Resources>
</UserControl>
这样在DataGrid中的Button就可以响应命令了。使用如下
<Button Content="修改" Command="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.CommandModify}"/>
有的时候,在windows 2003 Server的系统中,任务管理器灰掉了,点不了。问题原因也找不到,但可以临时解决
临时解决方案
1.开始->运行->gpedit.msc,打开组策略工具
2.在组策略工具中,用户配置->管理模版->系统->Ctrl+Alt+Del选项
3.把删除“任务管理器”那一项设置为“已禁用”,确定即可。有的时候已经选中的是已经禁用一项,不用理会,再选一次,确定,然后任务管理器就可以使用了。
昨天在一个项目的实施中,发现Silverlight控件不能显示,排除了JQuery脚本的影响,最后锁定为IIS的配置问题。
引起该问题的原因是IIS的安全设计,IIS只允许已知类型的恋恋不舍年由服务端向客户端派发并加载。因此,在使用VisFire的时候会发现,之前new Object都是正常的,而到后来在这个Object上挂载一个匿名的委托函数时,该函数不会执行,因此问题就比较容易解决了
解决方案:
1.添加IIS的MIME类型->“.xap”为“application”
有时候经常会遇到新装的Visual Studio 2008打开一个html或aspx页面时,不会高亮显示其间的内容。
这个问题原因应该是中文SQL安装时引起的,SQL会默认为VS安装一个中文的语言包,该包就VS而言不是完整包,会引起HtmlEditor包加载失败。
解决方案:
1.启动VS-Tools(工具)->Options(选项)->International Settings(区域语言设定),把其中的选项改为你安装VS的语言。
2.打开命令行工具(CMD),把目录转至VS的路径,键入命令“devenv /resetskippkgs”
完成后VS会被运行起来,最好再重启一下VS,问题得到了解决。

