2010-02-18 6 views
2

Я попытался найти ответ на этот вопрос, но мне не повезло. В основном у меня есть listview, связанный с коллекцией, возвращаемой из модели представления. Я привязываю выбранный элемент представления списка к свойству в моем списке, чтобы выполнить проверку, чтобы убедиться, что элемент выбран. Проблема в том, что иногда я хочу загрузить этот список с одним из уже выбранных элементов. Я надеялся, что смогу установить свойство на моей модели представления с выбранным объектом и автоматически выбрать этот элемент. Этого не происходит. Мои списки загружаются без выбранного элемента. Я могу успешно установить выбранный индекс в 0-й индекс, поэтому почему бы мне не удастся установить выбранное значение. Вид списка находится в режиме одиночного выбора.WPF ListView setting SelectedItem

Вот подходящий код из моего списка зрения

<ListView Name="listView1" ItemsSource="{Binding Path=AvailableStyles}" SelectionMode="Single"> 
      <ListView.SelectedItem> 
       <Binding Path="SelectedStyle" ValidatesOnDataErrors="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" BindingGroupName="StyleBinding" > 

       </Binding> 
      </ListView.SelectedItem> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="StyleImage"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <Image Source="800.jpg"/> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="Style Code" DisplayMemberBinding="{Binding StyleCode}"/> 
        <GridViewColumn Header="Style Name" DisplayMemberBinding="{Binding StyleName}"/> 
       </GridView> 
      </ListView.View> 
     </ListView> 

А вот уместный код с моей точкой зрения модели

public class StyleChooserController : BaseController, IDataErrorInfo, INotifyPropertyChanged 
{ 
    private IList<Style> availableStyles; 
    private Style selectedStyle; 

    public IList<Style> AvailableStyles 
    { 
     get { return availableStyles; } 
     set 
     { 
      if (value == availableStyles) 
       return; 

      availableStyles = value; 

      OnPropertyChanged("AvailableStyles"); 
     } 
    } 
    public Style SelectedStyle 
    { 
     get { return selectedStyle; } 
     set 
     { 
      //if (value == selectedStyle) 
      // return; 

      selectedStyle = value; 

      OnPropertyChanged("SelectedStyle"); 
     } 
    } 

    public StyleChooserController() 
    { 
     AvailableStyles = StyleService.GetStyleByVenue(1); 

     if (ApplicationContext.CurrentStyle != null) 
     { 
      SelectedStyle = ApplicationContext.CurrentStyle; 
     } 
    } 

    public string Error 
    { 
     get { return null; } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
      string error = string.Empty; 
      if (columnName == "SelectedStyle") 
      { 
       if (SelectedStyle == null) 
       { 
        error = "required"; 
       } 
      } 

      return error; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

} 

Я хотел бы отметить, что «Стиль» ссылка здесь имеет nothign сделать с WPF. Это бизнес-объект. Я действительно ищу решение, которое не нарушает шаблон MVVM, но я бы хотел получить что-то в этом роде. Я попытался пропустить список Listview.Items, чтобы установить его вручную, но при попытке всегда он пуст. Любая помощь приветствуется.

Редактировать: Я обновил код для использования INotifyPropertyChanged. Он все еще не работает. Любые другие предложения 2nd Edit: я добавил UpdateSourceTrigger = "PropertyChanged". Это все еще не сработало.

Благодаря

ответ

3

Ваша проблема, скорее всего, вызвана тем, что ваш SelectedItemStyle является другой Style экземпляр, чем согласование один в AvailableStyles в ItemsSource.

Что вам нужно сделать, это предоставить свое конкретное определение равенства в своем классе Style:

public class Style: IEquatable<Style> 
{ 
    public string StyleCode { get; set; } 
    public string StyleName { get; set; } 
    public virtual bool Equals(Style other) 
    { 
     return this.StyleCode == other.StyleCode; 
    } 

    public override bool Equals(object obj) 
    { 
     return Equals(obj as Style); 
    } 
} 
+0

Awesome ... Это действительно сработало. Есть ли лучший подход, который я не знаю? Это не плохое решение, но это заставляет меня делать то, что я делаю что-то неправильно. Основная причина, по которой я сделал отдельное свойство, состояла в том, чтобы проверить, что он был выбран в модели представления. В очередной раз благодарим за помощь. –

+0

Ваш подход прекрасен. Реализация IEquatable, как это, является хорошей практикой для ваших объектов модели. Ваша единственная альтернатива этому - убедиться, что экземпляр объекта SelectedItem содержится в коллекции ItemsSource (ссылочное равенство). Это может потребовать другого подхода к загрузке объектов в ваше приложение. –

0

Хм ... похоже, что вы забыли реализовать INotifyPropertyChanged для SelectedStyle собственности ...

+0

Спасибо за указание на это. Я попробовал это, и он все еще не работает. Я изменил свои автоматически реализованные свойства, чтобы иметь явные частные вары и инициировать событие в заданном свойстве. Все еще не выделяет или не изменяет выбранное значение. Это очень странно, потому что, когда вы предположили, что я думаю, что это сработает наверняка. Я отлаживал, чтобы убедиться, что это событие было уволено. –

+0

Я только немного подошел и обработчик был нулевым, поэтому он не подключался к событию. Я не совсем уверен, почему. Я подумал, указав привязку, что она была автоматической. Прошу прощения, так как это новичок, но ваша помощь приветствуется. –