Редактируемый WPF ListBox - PullRequest
5 голосов
/ 12 апреля 2009

У меня есть ObservableCollection, которая связана с ListBox в WPF. Я хочу, чтобы ListBox был редактируемым, а изменения редактирования были сохранены в коллекции. Поскольку WPF не предоставляет редактируемый список, я попытался создать свой собственный, изменив ListBox.ItemTemplate.

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

Изменение ItemTemplate дает мне редактируемые поля, но любые изменения в текстовых полях не сохраняются в ObservableCollection. Есть ли способ иметь редактируемый ListBox с двухсторонним связыванием?

Ответы [ 2 ]

8 голосов
/ 12 апреля 2009

Вы не можете сделать это таким образом.

Чтобы добиться такого трюка, вам нужно, чтобы ваши предметы были "классами держателей", которые предоставляют свойство, с которым вы можете связать свое текстовое поле.

Чтобы понять это, представьте следующую псевдопоследовательность вызовов:

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
    }
  }
}

Ваш шаблон (шаблон данных со списком) загружен, и элемент (который, как я полагаю, является строкой) передается внутрь. На данный момент он знает только строку и не может влиять на что-либо вверх. Двусторонняя привязка не может влиять на коллекцию, поскольку шаблон не знает, в каком контексте он используется, поэтому он не может обратиться к исходной коллекции и изменить ее содержимое. В этом отношении это то же самое для TextBox. Если ему не даны conainer и имя свойства, ему некуда «сохранить» изменения. Это в основном то же самое, что и передача строки в вызов функции. Функция не может изменить, какая строка была передана (игнорируя такие хитрости, как передача аргумента по ссылке).

Чтобы вернуться к вашему делу, вам нужно создать коллекцию объектов, которые предоставляют свойство, содержащее значение, которое необходимо отредактировать:

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

Затем вы можете привязать свой ListBox к коллекции этих элементов и изменить таблицу данных:

<ListBox.ItemTemplate>
    <DataTemplate>                                              
            <TextBox Name="EditableText" Text="{Binding Data, Mode=TwoWay}"/>
    </DataTemplate>
</ListBox.ItemTemplate>
0 голосов
/ 12 апреля 2009

Привязка к свойству модели, т. Е. Свойству объекта данных, а не к свойству вида, например Content. Например:

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

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

Обратите внимание, что это не будет работать, если ваш ItemsSource - ObservableCollection (потому что нет свойства для привязки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...