可编辑的 WPF 列表框

5

我有一个ObservableCollection,它绑定到WPF中的ListBox。我希望这个ListBox是可编辑的,并且对编辑所做的更改可以保存到集合中。由于WPF不提供可编辑的listbox,因此我尝试通过更改ListBox.ItemTemplate来创建自己的listbox。

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

更改ItemTemplate可以给我可编辑的框,但是对文本框所做的任何更改都不会保存到ObservableCollection中。有没有一种方法可以拥有具有双向绑定的可编辑ListBox?
2个回答

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。如果没有给它容器和属性名称,它就没有地方“存储回”更改。基本上,这就像将字符串传递到函数调用中一样。函数无法更改传入的字符串(忽略诸如按引用传递参数等技巧)。回到您的情况,您需要构建一个对象集合,其中包含需要编辑的值的属性。
public class MyDataItem
{
  string Data { get; set;}
}

然后,您可以将ListBox绑定到这些项目的集合并修改datatemplate:
<ListBox.ItemTemplate>
    <DataTemplate>                                              
            <TextBox Name="EditableText" Text="{Binding Data, Mode=TwoWay}"/>
    </DataTemplate>
</ListBox.ItemTemplate>

我有一个类似的问题,但由于我对WPF非常陌生,所以不知道如何编写{Binding Data,Mode = TwoWay},如果我有一组字符串列表,并且没有可以绑定的实际属性。 - Sergej Andrejev
1
你不能这样做,这就是我的答案的重点... 你需要将字符串列表转换为对象列表(每个对象包含一个字符串,可以通过属性访问),并在ListBox中显示该次级列表。 - Denis Troller

0
绑定到模型属性 - 即数据对象的属性 - 而不是视图属性,如Content。例如:
// model class
public class Widget : INotifyPropertyChanged
{
  public string Description { ... }
}

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

请注意,如果您的ItemsSource是ObservableCollection(因为没有要绑定的属性),则此方法将无法正常工作。

我认为我不能直接将文本框文本绑定到数据对象。在您的示例中,您绑定到单个字符串,但我的类有一个字符串集合,我无法将Text属性设置为字符串列表。 - Daniel Delaney
DataTemplate 会为 Items 集合中的每个成员重复一次,绑定设置为该成员。 - itowlson

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