找回密码
 立即注册

QQ登录

只需一步,快速开始

fxdmhtt

初级会员

9

主题

38

帖子

221

积分

初级会员

积分
221

活字格认证微信认证勋章

fxdmhtt
初级会员   /  发表于:2015-8-22 17:44  /   查看:10917  /  回复:11
数据源定义如下:
        public ObservableCollection<Dictionary<string, object>> Data
        {
            get { return _data; }
            set { _data = value; }
        }
因业务逻辑和底层架构需要,对DataGrid的Column设置Binding。Binding的path是Dictionary的Key,而key是A.B.C结构,例如text.two.x。data为json逆序列化出的对象。
            for (int i = 0; i < 5; i++)
            {
                Dictionary<string, object> row = new Dictionary<string, object>();
                row.Add("text-one-x", string.Format("{0}{1}", Convert.ToChar('A' + i), i));
                row.Add("text.two.x", string.Format("{0}{1}", Convert.ToChar('A' + i), i));
                row.Add("num-one-x", i);
                row.Add("num.two.x", i);
                Data.Add(row);
            }

            dg.Columns.Add(new C1.WPF.DataGrid.DataGridTextColumn() { Header = "文本(横线)", Binding = new Binding("[text-one-x]") });  // 正常
            dg.Columns.Add(new C1.WPF.DataGrid.DataGridTextColumn() { Header = "文本(点)", Binding = new Binding("[text.two.x]") });  // 异常
            dg.Columns.Add(new C1.WPF.DataGrid.DataGridNumericColumn() { Header = "数值(横线)", Binding = new Binding("[num-one-x]") });  // 正常
            dg.Columns.Add(new C1.WPF.DataGrid.DataGridNumericColumn() { Header = "数值(点)", Binding = new Binding("[num.two.x]") });  // 异常
那么,DataGrid的排序和筛选都失效,且筛选的右箭头点开时还抛异常。
请问,在不修改数据结构和命名规范(几乎不可能再修改了)的情况下,如何让DataGrid正确工作?

11 个回复

倒序浏览
fxdmhtt
初级会员   /  发表于:2015-8-22 17:46:00
沙发


这是demo,供老师测试。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
KNight
中级会员   /  发表于:2015-8-23 12:42:00
板凳
回复 2楼fxdmhtt的帖子

XAML中的数据绑定详见:https://msdn.microsoft.com/zh-cn/library/ms742451(v=vs.110).aspx
如果直接用[A.B.C]结构进行绑定,它会解析成A对象里的B对象里的C进行绑定,而不是作为一个整体,才会导致你说的异常;如果一定要用该结构进行绑定,加入转义符号^即可;
  1. dg.Columns.Add(new C1.WPF.DataGrid.DataGridTextColumn() { Header = &quot;文本(点)&quot;, Binding = new Binding(&quot;[text^.two^.x]&quot;) });
复制代码

评分

参与人数 1金币 +500 收起 理由
Alice + 500 谢谢专业的解释。奖励500金币

查看全部评分

回复 使用道具 举报
Alice
社区贡献组   /  发表于:2015-8-24 12:54:00
地板
回复 1楼fxdmhtt的帖子

请参考3楼的回复,请问问题解决了么
请点击评分,对我的服务做出评价!  5分为非常满意!

葡萄城控件服务团队

官方网站: http://www.gcpowertools.com.cn
回复 使用道具 举报
fxdmhtt
初级会员   /  发表于:2015-8-24 13:59:00
5#
回复 3楼KNight的帖子

似乎问题不出在这里。
事实上我在项目中不是直接硬规定的path,而是一个string:
Binding = new Binding(string.Format(&quot;[{0}]&quot;, key))
不存在这个情况吧?

另外并不是binding失败,因为毕竟数据能够出来,只是c1datagrid的排序、筛选功能会失败。请老师再帮我看看,谢谢。
回复 使用道具 举报
fxdmhtt
初级会员   /  发表于:2015-8-24 14:11:00
6#
回复 4楼Alice的帖子

并没有解决,请老师再帮我看看。这个问题挺严重的。谢谢。
回复 使用道具 举报
KNight
中级会员   /  发表于:2015-8-24 15:29:00
7#
回复 6楼fxdmhtt的帖子

加入转义字符没有解决?

下面是报错提示:
  1. 在 System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
  2.    在 System.String.Substring(Int32 startIndex, Int32 length)
  3.    在 C1.WPF.Extensions.GetPropertyValue(Object target, String path)
  4.    在 C1.WPF.Extensions.GetPropertyValue(Object target, String path)
  5.    在 C1.WPF.Extensions.GetPropertyValue[T](Object target, String path)
  6.    在C1.WPF.DataGrid.GetPropertyValue[T](Object source, String propertyPath)
  7.    在 C1.WPF.DataGrid.Filters.C1AdvancedFiltersBehavior.<>c__DisplayClass34.<GetColumnValues>b__31(Object o)
复制代码


可以看到Path会传入到DataGrid.GetPropertyValue方法中,并最终在C1.WPF.Extensions.GetPropertyValue中处理,而该方法如下:
  1. internal static object GetPropertyValue(this object target, string path)
  2. {
  3.     if (target == null)
  4.     {
  5.         return null;
  6.     }
  7.     if (string.IsNullOrEmpty(path))
  8.     {
  9.         return target;
  10.     }
  11.     if (path.Contains("."))
  12.     {
  13.         return target.GetPropertyValue(path.Substring(0, path.IndexOf('.'))).GetPropertyValue(path.Substring(path.IndexOf('.') + 1));
  14.     }
  15.     if (path.Contains("["))
  16.     {
  17.         int num;
  18.         string str = path.Substring(0, path.IndexOf('['));
  19.         string s = path.Substring(path.IndexOf('[') + 1, (path.IndexOf(']') - path.IndexOf('[')) - 1);
  20.         if (int.TryParse(s, out num))
  21.         {
  22.             if (string.IsNullOrEmpty(str))
  23.             {
  24.                 return target.GetType().GetProperty("Item", null, new Type[] { typeof(int) }).GetValue(target, new object[] { num });
  25.             }
  26.             return target.GetPropertyValue(str).GetPropertyValue(path.Substring(path.IndexOf('['), (path.IndexOf(']') - path.IndexOf('[')) + 1));
  27.         }
  28.         if (string.IsNullOrEmpty(str))
  29.         {
  30.             return target.GetType().GetProperty("Item", null, new Type[] { typeof(string) }).GetValue(target, new object[] { s });
  31.         }
  32.         return target.GetPropertyValue(str).GetPropertyValue(path.Substring(path.IndexOf('['), (path.IndexOf(']') - path.IndexOf('[')) + 1));
  33.     }
  34.     PropertyInfo property = target.GetType().GetProperty(path);
  35.     if (property == null)
  36.     {
  37.         return null;
  38.     }
  39.     return property.GetValue(target, null);
  40. }
复制代码

可以看到它是根据'.'来处理的,分割传入的Path,然后去取对应的属性内容;而你自定义的[A.B.C],它必然会去取A属性下的B属性下的C属性(类似描述吧,本人表达能力有限:-| ),这样肯定会报错啊
回复 使用道具 举报
Alice
社区贡献组   /  发表于:2015-8-24 17:11:00
8#
回复 7楼KNight的帖子

谢谢@KNight。
请点击评分,对我的服务做出评价!  5分为非常满意!

葡萄城控件服务团队

官方网站: http://www.gcpowertools.com.cn
回复 使用道具 举报
fxdmhtt
初级会员   /  发表于:2015-8-24 21:02:00
9#
回复 8楼Alice的帖子


然而实测确实没解决问题,并且Microsoft的文档也是说在xaml下转义,并且是Microsoft的类库才具有此特性。
而目前我是在C#下通过string提供的path进行绑定,并且是对C1DataGrid进行绑定。
根据老师的指导修改的代码如下:请调试。

谢谢。
实在不想改命名约定,麻烦大了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
KNight
中级会员   /  发表于:2015-8-25 22:09:00
10#
回复 9楼fxdmhtt的帖子

加转义符号是我弄错了,Sorry:|

通过在C1.WPF.Extensions.GetPropertyValue(...)处加断点调试可知,Binding的Path值是会根据分隔符[.]来逐层取得属性值的,所以,放弃治疗吧...还不如改一下绑定的Key值:2!






截到&quot;[num&quot;时,查找结束符号&quot;]&quot;时报异常;

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部