可编辑的WPF ListBox

时间:2009-04-12 05:58:07

标签: c# wpf data-binding

我有一个ObservableCollection绑定到WPF中的ListBox。我希望ListBox可以编辑,并将编辑更改保存到集合中。由于WPF不提供可编辑的列表框,我尝试通过更改ListBox.ItemTemplate来创建自己的列表框。

<ListBox.ItemTemplate>
    <DataTemplate>                      
        <TextBox Name="EditableText" Text="{TemplateBinding Content}"/>
    </DataTemplate>
</ListBox.ItemTemplate>

更改ItemTemplate会为我提供可编辑的框,但对文本框的任何更改都不会保存到ObservableCollection中。有没有办法让可编辑的ListBox具有双向绑定?

2 个答案:

答案 0 :(得分:8)

你不能这样做。

要实现这种技巧,您需要将您的项目设置为“持有者类”,以显示可以将文本框绑定到的属性。

要理解它,请想象以下伪序列的调用:

class ListBox
{
  Bind(Items)
  {
    foreach(var item in Items)
    {
      DataTemplate Template = LoadTemplateForItem(item.GetType()); // this is where your template get loaded
      Template.Bind(item); //this is where your template gets bound
    }
  }
}

您的模板(带有列表框的DataTemplate)已加载,并且项目(我假设是您的情况下的字符串)将被传入。 此时,它只知道字符串,不能向上影响任何东西。双向绑定不能影响集合,因为模板不知道它在哪个上下文中使用,因此它无法返回到原始集合并修改其内容。 就此而言,TextBox也是如此。如果没有给出变量和属性名称,则无法“存储”更改。 这与将字符串传递给函数调用基本相同。该函数无法更改传入的字符串(忽略诸如by-reference参数传递之类的技巧)。

要回到您的案例,您需要构建一个对象集合,这些对象公开包含需要编辑的值的属性:

public class MyDataItem
{
  string Data { get; set;}
}

然后,您可以将ListBox绑定到这些项的集合并修改您的datatemplate:

<ListBox.ItemTemplate>
    <DataTemplate>                                              
            <TextBox Name="EditableText" Text="{Binding Data, Mode=TwoWay}"/>
    </DataTemplate>
</ListBox.ItemTemplate>

答案 1 :(得分:0)

绑定到模型属性(即数据对象的属性),而不是绑定到视图属性(如Content)。例如:

// model class
public class Widget : INotifyPropertyChanged
{
  public string Description { ... }
}

<!-- view -->
<DataTemplate>
  <TextBox Text="{Binding Description}" />
</DataTemplate>

注意,如果您的ItemsSource是ObservableCollection(因为没有要绑定的属性),这将不起作用。