在 Silverlight/WPF 中绑定复杂属性
Posted
技术标签:
【中文标题】在 Silverlight/WPF 中绑定复杂属性【英文标题】:Binding complex properties in Silverlight/WPF 【发布时间】:2010-10-16 19:25:33 【问题描述】:假设我有一个看起来像这样的自定义数据类型:
public class MyDataType
public string SimpleProp1;
public string SimpleProp2;
public List<SomeType> ComplexProp;
现在我有一个动态创建的数据绑定控件(即 ItemsControl 或 DataGrid)。 xaml 代码中定义的绑定如何访问复杂属性的子属性?我认为它应该看起来像这样:
<TextBox Text="Binding simpleSubProp, path=ComplexProp[0]" />
或
<TextBox Text="Binding path=ComplexProp[0].simpleSubProp" />
但是这两个都给了我 xml 解析错误。它应该如何正确显示?甚至可以以这种方式引用集合属性的特定项目吗?如果不是,我还有什么其他选择?
编辑,场景似乎不够清晰:
我有一个
IEnumberable<MyDataType>
绑定到 ItemsControl,在 DataTemplate 内我有多个 TextBox,需要引用复杂属性列表中对象的子属性。
【问题讨论】:
【参考方案1】:我不确定你能做到这一点。通常,您会将列表绑定到列表框(或另一个“重复”控件)之类的东西上,然后其中的每个项目都将能够绑定到列表中的相关元素。
【讨论】:
我可能还不够清楚,我有一个绑定到 ItemsControl 的 IEnumerable试试 Binding ComplexProp(0).simpleSubProp。如果这不起作用,您也可以编写一个简单的转换器来执行此操作。
【讨论】:
感谢您的回答,不幸的是,这给了我一个 System.ArgumentException“无效的绑定路径;字符”。这个转换器的外观如何?我认为转换器通常用于以特定方式格式化数据【参考方案3】:根据Path Syntax on MSDN,你可以这样做:
<TextBox Text="Binding ComplexProp[0].simpleSubProp" />
可能是小写的“path=”给了你错误?试试“路径=”。另外,不确定这是否适用于 Silverlight...
【讨论】:
该页面用于 WPF,而不是 Silverlight。 Silverlight 不支持绑定中的索引属性。 问题的标题是“Silverlight/WPF”。 索引方法似乎只适用于 Silverlight 中的某些情况,不过谢谢! Silverlight 3 支持绑定中的索引属性。【参考方案4】:Silverlight Indexers in property paths are broken 中的 poperty 路径索引器似乎已损坏。绕过它的方法是在帖子中建议并使用 IValueConverter。
XAML
<UserControl x:Class="Silverlight.Mine.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="System"
xmlns:sm="clr-namespace:Silverlight.Mine;assembly=Silverlight.Mine"
Width="400" Height="300">
<UserControl.Resources>
<sm:SomeTypeConverter x:Key="MySomeTypeConverter" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="myTextBlock" Text="Binding Path=SomeDates, Converter=StaticResource MySomeTypeConverter" />
</Grid>
</UserControl>
C# Page.xaml.cs
namespace Silverlight.Mine
public partial class Page : UserControl
private SomeType m_mySomeType = new SomeType();
public Page()
InitializeComponent();
myTextBlock.DataContext = m_mySomeType;
C# SomeType.cs
namespace Silverlight.Mine
public class SomeType
public List<DateTime> SomeDates get; set;
public SomeType()
SomeDates = new List<DateTime>();
SomeDates.Add(DateTime.Now.AddDays(-1));
SomeDates.Add(DateTime.Now);
SomeDates.Add(DateTime.Now.AddDays(1));
public class SomeTypeConverter : IValueConverter
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
if (value != null)
List<DateTime> myList = (List<DateTime>)value;
return myList[0].ToString("dd MMM yyyy");
else
return String.Empty;
public object ConvertBack(object value,
Type targetType,
object parameter,
CultureInfo culture)
if (value != null)
return (List<DateTime>)value;
return null;
【讨论】:
【参考方案5】:我一直都在做这种事情,有两种方法可以解决这个问题,具体取决于你想从中得到什么。
如果您真的只想要列表中的一个特定成员,您可以使用转换器。 XAML 看起来像这样:
<TextBox Text="Binding MyDataTypeInstance, Converter=StatacResources SpecificInstanceConverter" />
不过,这通常不是我需要的,通常我需要一个控件来显示整个复杂对象,如果是这种情况,方法更像如下:
<StackPanel>
<Textblock Text="Binding SimpleProp1"/>
<TextBlock Text="Bidning SimpleProp2"/>
<ItemsControl ItemsSource="Binding ComplexProp>
<ItemsControl.ItemsTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="Binding ComplexPropertyName/>
<InputToolkit:NumericUpDown Value="Binding ComplexPropertyValue/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemsTemplate>
</ItemsControl>
</StackPanel>
我喜欢这种方法,因为我的 GUI 与我的业务对象匹配,因此它通常比我在代码隐藏中检查特定索引时干净得多。
【讨论】:
【参考方案6】:为了概括这一点,我建议你使用其他人提到的值转换器,并使用 ConverterParam 选项来传递索引。
【讨论】:
【参考方案7】:这在 Silverlight 4 中现在可以正常工作了。
需要注意的是,该类有三个公共字段。将它们更改为属性(并且也是实现 INotifyPropertyChanged 的一个想法),然后下面的代码就可以工作了。
<StackPanel>
<TextBlock Text="Binding Path=SimpleProp1" />
<TextBox Text="Binding Path=ComplexProp[0].SimpleSubProp, Mode=TwoWay" Width="200" Height="60"/>
</StackPanel>
大小写也很重要,因为绑定区分大小写。
【讨论】:
以上是关于在 Silverlight/WPF 中绑定复杂属性的主要内容,如果未能解决你的问题,请参考以下文章
.NET 开发的未来:ASP.NET 还是 WPF/Silverlight/Winforms? [关闭]
如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?