2014-04-04 2 views
0

У меня есть пользовательский интерфейс, который позволяет вам выбрать команду слева, а затем отредактировать свойства выбранной команды справа. Вот пример сценарий демонстрирует вопрос:ListView не обновляется, когда наблюдаются изменения коллекции?

  1. Выбор Дракона команда
  2. Переименовать Smaug, нажмите сохранить.
    1. «Дракон» в панели выбора слева не обновляется до «Smaug». Однако, если я выберу другую команду, повторно выберите «Дракон», текстовое поле с правой стороны все еще (правильно) показывает «Smaug». Я уверен, что это означает, что коллекция данных привязки правильно обновляется.
  3. Закройте окно настроек, затем снова откройте его.
  4. Левая панель теперь (правильно) показывает «Smaug».

The UI

Список команд в настоящее время хранятся в качестве наблюдаемой коллекции:

public class TeamList : ObservableCollection<Team> 
{ 
    public TeamList() : base() { } 
} 

список команды на левом заселяются/занной:

SettingsWindow.xaml

<ListView ItemsSource="{Binding}" Grid.Column="0" Grid.Row="1" DisplayMemberPath="name" 
      SelectionChanged="ListTeamSelected" SelectionMode="Single"> 
    <!--<ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="Foreground" Value="{Binding color}" /> 
     </Style> 
    </ListView.ItemContainerStyle>--> 
</ListView> 

SettingsWindow.xaml.cs

public Team selectedTeam { get; set; } 

    public SettingsWindow() 
    { 
     teams = TeamManager.Instance().teamList; 
     this.DataContext = this.teams; 
     if (!Application.Current.Resources.Contains("selectedTeam")) 
      Application.Current.Resources.Add("selectedTeam", selectedTeam); 
     InitializeComponent(); 
    } 

Данные о праве заселяется и сохранены:

SettingsWindow.xaml.cs

private void ClickSaveData(object sender, RoutedEventArgs e) 
{ 
    selectedTeam.name = TeamName.Text; 
    selectedTeam.color = PrimaryColorPicker.SelectedColor; 
    selectedTeam.secondaryColor = SecondaryColorPicker.SelectedColor; 
    saved = true; 
} 

private void ListTeamSelected(object sender, RoutedEventArgs e) 
{ 
    selectedTeam = (Team)(sender as ListView).SelectedItems[0]; 
    TeamInfo.Visibility = Visibility.Visible; 
    TeamName.Text = selectedTeam.name; 
    PrimaryColorPicker.SelectedColor = selectedTeam.color; 
    SecondaryColorPicker.SelectedColor = selectedTeam.secondaryColor; 
} 

Twofold вопрос:

  1. Я делаю что-то не так с моей привязкой данных, которая вызывает эту проблему? (Я новичок в WPF)

  2. Если нет, есть ли способ заставить пользовательский интерфейс обновить список слева? (это кажется смутно неудобным для меня)

Заранее благодарю за любую помощь!

+0

ли ваши свойства реализации INotifyPropertyChanged? – reggaeguitar

+0

См. Http://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist и http://wpftutorial.net/INotifyPropertyChanged.html – reggaeguitar

+0

Не понял, что это было. Благодаря! Вы хотите опубликовать его в качестве ответа, чтобы я мог отметить его как ответ? – Benjin

ответ

0

Для правильной работы ваших свойств необходимо реализовать интерфейс INotifyPropertyChanged для привязки данных. Например (из http://wpftutorial.net/INotifyPropertyChanged.html)

private string _name; 

public string Name 
{ 
    get { return _name; } 
    set 
    { 
     _name = value; 
     PropertyChanged("Name"); 
    } 
} 

private void PropertyChanged(string prop) 
{ 
    if(PropertyChanged != null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(prop); 
    } 
} 

Я очень рекомендую MVVM Light Toolkit для любой MVVM работы, хотя (https://mvvmlight.codeplex.com/). Если вы используете MVVM Light Toolkit, то вы можете наследовать от ViewModelBase, а затем реализовать свои свойства, как этот

private string _orgId; 
    public string OrgId 
    { 
     get { return _orgId; } 
     set { _orgId = value; RaisePropertyChanged("OrgId"); } 
    } 
0

Я не знал, что мой класс Team реализует INotifyPropertyChanged. This link был очень полезен и прост. Пару вещей, чтобы отметить для тех, кто никогда не работал с привязкой данных перед:

  1. Вы должны геттеры и сеттеры для всех свойств, которые вы хотите уведомить о, чтобы бросить событие.

  2. Вам нужно использовать частные переменные для хранения самих данных, или сеттер будет запускаться сам, перебрасывая вас в переполнение стека.

  3. Параметр для события - это публичное имя измененного свойства, а не личное имя или значение.

Спасибо @ReggaeGuitar за ответ!

Смежные вопросы