【发布时间】:2014-04-24 21:11:39
【问题描述】:
编辑:这是问题的另一个(更简单)版本:
假设我有一个带有TextBox 的应用程序用于搜索人员(在数据库、本地存储等中)。键入人员时,搜索完成,UI 应根据找到的人员进行更新。在我的例子中,UI 包含一个 TextBlock,显示属性 Person.ShortName 的值。
为此,我需要使用具有以下想法的辅助类 PersonQueryCreator:
public class PersonQueryCreator : DependencyObject
{
#region Static Data Members
public static DependencyProperty ShortNameToSearchProperty = DependencyProperty.Register("ShortNameToSearch", typeof(string), typeof(PersonQueryCreator), new PropertyMetadata(UpdateQueryObject));
private static DependencyPropertyKey QueryPropertyKey = DependencyProperty.RegisterReadOnly("Query", typeof(string), typeof(PersonQueryCreator), new PropertyMetadata());
public static DependencyProperty QueryProperty = QueryPropertyKey.DependencyProperty;
#endregion
#region Public Properties
public string ShortNameToSearch
{
get { return (string)GetValue(ShortNameToSearchProperty); }
set { SetValue(ShortNameToSearchProperty, value); }
}
public object Query
{
get { return (string)GetValue(QueryProperty); }
}
#endregion
#region Public Methods
public static IPerson SearchForPerson(object query)
{
...
}
#endregion
}
这个类有一些属性我可以设置来创建查询(在这个例子中我将使用PersonQueryCreator.ShortNameToSearch),它产生一个查询对象,该对象在属性PersonQueryCreator.Query中返回。该类还提供了一个静态方法PersonQueryCreator.SearchForPerson,它接受一个查询参数并返回一个Person 对象。
所以我必须使用转换器在TextBlock 中显示正确的人的短名称。我可以将短名称TextBlock 直接绑定到搜索TextBox 并使用转换器查询并返回ShortName 属性。但是,如果我这样做,那么如果 Person.ShortName 内容发生更改(不更改 Person 对象引用本身),TextBlock 将不会更新。
原来的问题在这里
我有一个 DAL 对象包含一个人的集合。 DAL 对象定义了人员之间关系的有向树图,我想显示一个人的“孩子”相关人员的ListBox。
由于关系是在 DAL 中而不是在 person 对象中定义的,因此我需要定义一个知道使用适当 DAL 方法的应用逻辑。因此,我使用ListBox.ItemsSource Binding 中使用的转换器,如下所示(对不起,代码隐藏样式:))。
BindingBase relationsBinding = new MultiBinding()
{
Bindings =
{
new Binding() { Source = this, Path = new PropertyPath("Person") },
new Binding() { Source = this, Path = new PropertyPath("DAL") }
},
Converter = PersonToRelationsConverter.Instance,
};
ListBox relationsList = new ListBox()
{
ItemTemplate = relationsBinding
};
relationsList.SetBinding(ListBox.ItemsSourceProperty, relationsBinding);
转换器代码类似于:
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
IPerson person = values[0] as IPerson;
IDAL<IPerson> dal = values[1] as IDAL<IPerson>;
IPersonRelations<IPerson> relations = dal.GetPersonRelations(person);
IEnumerable<IPerson> children = relations.OutRelated;
return children;
}
然后我可以使用 ItemTemplate 来定义每个孩子的显示方式。
它可能有效,但问题是IPersonRelations<IPerson> 是一个INotifyPropertyChanged 对象,我想享受它的数据更改通知。上述方式我无法享受它,因为它只是ValueConverter 的局部变量,不会返回到WPF 机制。
我猜ListBox.ItemsSource 只是IValueConverter 必须返回某些特定对象而不是INotifyPropertyChanged 或DependencyObject 的示例(或者不是我希望绑定监听的唯一对象) )。我希望有一些 CompositeBinding 类允许“连接”ValueConverters,因此绑定机制将监听连接“路径”中的任何值。
我是否想念一些非常简单的方法来做这样的事情?
感谢您的帮助。
【问题讨论】:
-
你搞错了。您的转换器不应该访问 DAL 的东西,这就是 VM 应该做的。并且请不要在 WPF 的程序代码中创建或操作 UI 元素。这就是 XAML 的用途。
-
首先,请留下代码隐藏问题,我已经在我的消息中提到了它,代码仅用于示例。其次,除了作为一个很好的设计建议之外,我不明白 MVVM 基础知识将如何解决我获取有关数据更改的通知的主要问题。
标签: c# wpf binding listbox dependency-properties