XAML中的数据绑定(多向绑定?)

3
假设我有一个ListBox,在代码后端绑定了一些内容:
<ListBox x:Name="list">
   <ListBox.ItemTemplate>
      <DataTemplate>
         <ListBoxItem Content="{Binding Name}" />
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

<TextBox x:Name="name" Text="{Binding ElementName=list, Path=SelectedItem.Name, Mode=TwoWay" />
<TextBox x:Name="contents" Text="{Binding ElementName=list, Path=SelectedItem.Contents, Mode=TwoWay" />

代码后台:

public class Dude
{
   public String Name { get; set; }
   public String Contents { get; set; }
}

现在,以上内容对我来说已经足够好了。当选择列表框中的项目时,文本框将更新以显示列表框中所选内容。

但是,我现在正在尝试通过向我的Dude类添加字典来扩展它:

public class Dude
{
   public string Name { get; set; }
   public string Contents { get; set; }
   public Dictionary<String, String> Tasks { get; set; }
}

希望我能够:在ListBox中点击一个项目后,将对应项目的名称和内容属性显示在其各自的文本框中,然后将Dictionary内容的Key/Value附加到内容文本框中。但是我不知道如何深入研究它。感觉有点像多级绑定,我需要什么?你有任何(简单)的示例吗?有没有文档、文章、教程?非常感谢您的帮助。谢谢。

2
我认为更好的解决方案可能涉及到一个列表框或其他ItemsControl,你可以将其绑定到Tasks属性,而不是将Tasks对添加到你已经绑定到Contents属性的控件中。但是,我很久没有做XAML绑定了,所以现在我没有更好的答案,很抱歉。祝你好运! - phoog
1
这可能会有用http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/。 - user857521
1
你的字典必须是静态的,否则我看不出有什么用处。你可以更改绑定以使其在目标更新时发出通知,然后捕获TargetUpdated事件。(http://msdn.microsoft.com/zh-cn/library/system.windows.data.binding.notifyontargetupdated.aspx) - GameAlchemist
1个回答

3
你希望的可以在WPF中实现(在其他XAML技术如Wp7或WinRT中可能有些困难),但是我不确定这是否符合你的需求...
使用MultiBinding,将Contents字符串和Tasks字典都绑定到第二个文本框,然后编写自己的IMultiValueConverter来构建你想要显示的字符串。
阅读关于MultiBindings的教程在这里,粗略的代码应该看起来像这样:
<TextBox>
   <TextBox.Text>
      <MultiBinding Converter="{StaticResource YourAppendingConverter}">
         <Binding ElementName="list" Path="SelectedItem.Contents" />
         <Binding ElementName="list" Path="SelectedItem.Tasks" />
      </MultiBinding>
   </TextBox.Text>
</TextBox>

你的转换器应该类似于:

public class YourAppendingConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, 
      System.Globalization.CultureInfo culture){
       StringBuilder sb = new StringBuilder(values[0].ToString());
       sb.AppendLine("Tasks:");
       foreach (var task in (Dictionary<string,string>)values[1]){
         sb.AppendLine(string.Format("{0}: {1}", task.Key, task.Value));
       }
       return sb.ToString();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, 
      System.Globalization.CultureInfo culture){
        throw new NotSupportedException();
    }

为什么我认为这是你需要的?
1. 如果需要编写ConvertBack,那么会很麻烦 - 所以这个TextBox应该是只读的。 2. Dictionary不会通知。如果在显示时基础字典发生更改,那么什么也不会改变。
如果您仔细思考了这些问题,那么 MultiBinding 可能是您需要的工具。

哇,非常感谢 @TDaver。就像这样的时候,我真的很怀念 WinForms 的简单性。 - Protected Identity
1
@ProtectedIdentity:我觉得这样更合乎逻辑 :) - TDaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接