所以我正在完成我的第一个WPF项目,我喜欢到目前为止看到的内容。学习曲线比我预期的要多,但WPF非常酷。但是,我正在努力解决数据绑定概念。我遇到的一个具体问题是如何使我的数据绑定声明重构安全?考虑这个例子。
public class MyDataObject
{
public string FooProperty { get; set; }
}
void Bind()
{
var gridView = myListView.View as GridView;
gridView.Columns.Clear();
gridView.Columns.Add(
new GridViewColumn()
{
Header = "FooHeader",
DisplayMember = new Binding("FooProperty")
}
);
List<MyDataObject> source = GetData();
myListView.ItemsSource = source;
}
那么如果我将数据对象上的FooProperty重命名为其他内容呢?数据绑定将无效,我不会收到编译错误,因为绑定是通过文本声明的。有没有办法让绑定更加安全?
答案 0 :(得分:3)
您可以使用lambda表达式来表示属性名称,而不是直接使用名称:
protected static string GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> expression)
{
if (expression.NodeType == ExpressionType.Lambda && expression.Body.NodeType == ExpressionType.MemberAccess)
{
PropertyInfo prop = (expression.Body as MemberExpression).Member as PropertyInfo;
if (prop != null)
{
return prop.Name;
}
}
throw new ArgumentException("expression", "Not a property expression");
}
你可以这样使用它:
...
DisplayMember = new Binding(GetPropertyName((MyDataObject o) => o.FooProperty))
...
好的,它有点冗长......如果你想要更短的东西,你也可以创建一个辅助方法:
public Binding CreateBinding<TSource, TResult>(Expression<Func<TSource, TResult>> expression)
{
return new Binding(GetPropertyName(expression))
}
...
DisplayMember = CreateBinding((MyDataObject o) => o.FooProperty)
...
这样,如果重命名属性,重构应该可以正常工作(当然除了XAML ......)
答案 1 :(得分:2)
重构依赖于工具支持,可以识别代码中的特定符号(C#,XAML,config等...)何时表示要重命名的标识符。
在您提供的示例中,字符串文字"FooProperty"
无法100%被解释为属于MyDataObject
,而不了解GridView
的内部工作原理以及所有其他类型的扩展在WPF和其他框架中。
但是,在DataTemplate中,可以99%确定:
<DataTemplate DataType="{x:Type local:MyDataObject}">
<TextBlock Text="{Binding Path=FooProperty}" />
</DataTemplate>
我使用(并发誓)一个名为ReSharper(又名R#)的IDE插件,它对这些事情非常聪明。如果您重命名FooProperty
,R#将自动为您重命名该属性。
在您的示例中,如果您要重命名该属性,R#仍然可以使用。它会在文字(您的情况)和注释中找到字符串的所有实例(如果您已注释掉某些代码并且稍后可能会取消注释,则非常有用)。您将获得一个树视图,在上下文中显示每个文字,您可以在继续之前检查/取消选中各个用法/文件/文件夹/项目。
如果您的预算允许,请获取R#。如果您的预算不允许,请下载试用版,并在结束时,您的预算会找到空间。确保打印出快捷键的副本以改善您的学习体验。
答案 2 :(得分:0)
您可以使用反射来确定您的媒体资源的名称。当然,如果每个类有多个绑定,这是有问题的,因此可能另外使用自定义属性(也可通过反射获得)来获取关于命名属性应绑定到的正确绑定字段的“提示”。
这很可能最终只是将不可重构的魔术字符串重新定位到应用程序的不同部分,但我不能说我已经尝试过并且让它工作了。