2013-05-14 2 views
5

Я работаю над приложением WPF и после MVVM. На мой взгляд, есть сетка, которая содержит разные столбцы. Один из этих столбцов - ListBox. Теперь проблема в том, что для столбца ListBox SelectedItem get отлично работает, но нет.ListBox selectedItem работать, но не работает в MVVM

Вот мой код Просмотр

<DataGrid ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" SelectionMode="Single"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding Name}" Header="Name" /> 
     <DataGridTemplateColumn Header="Actions"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Actions}" SelectedItem="{Binding SelectedAction}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

В моей ViewModel, у меня есть Главный ViewModel класс, который содержит список элементов. Класс объекта содержит имя, список действий и выбранное действие.

public class MyViewModel : INotifyOfPropertyChanged 
{ 
    private ObservableCollection<Item> _items; 
    public ObservableCollection<Item> Items 
    { 
     get { return _items?? (_items= new ObservableCollection<Item>); } 
    } 

    private Item _selectedItem; 
    public Item SelectedItem 
    { 
     get { return _selectedItem; } 
     set { _selectedItem= value; } 
    } 
} 

public class Item : INotifyOfPropertyChanged 
{ 
    public string Name; 

    private ObservableCollection<string> _actions; 
    public ObservableCollection<string> Actions 
    { 
     get { return _actions?? (_actions= new ObservableCollection<string>); } 
    } 

    private string _selectedAction; 
    public string SelectedAction 
    { 
     get { return _selectedAction; } 
     set { _selectedAction = value; } 
    } 
} 

Now SelectedItem for Items list отлично работает. Но SelectedItem insde Класс Item для Actions не работает полностью. Я вставил контрольные точки на геттер и сеттер SelectedAction. получить обратные точки. Но если я выберу действие из пользовательского интерфейса, тогда установить точку останова для SelectedAction не получится.

В чем проблема.

View

Когда я выбираю архив проекта или восстановления проекта, законодательницей SelectedAction не дозвонились.

Примечание: Я извлекал ненужной информации, как загрузка данных в списках, реализации INotifyOfPropertyChanged и т.д.

+0

проводке «Теперь SelectedItem для элементов списка работает отлично ...», где эта часть кода, который работает отлично? – MikroDel

+0

@MikroDel в классе MyViewModel. SelectedItem. –

+0

Объект DataGrid привязан к элементам (списку) в классе MyViewModel. –

ответ

1

Вот исправление. Нам нужно установить UpdateSourceTrigger для ListBox для SelectedItem,

<DataTemplate> 
    <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Actions}" SelectedItem="{Binding SelectedAction, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
</DataTemplate> 
2

SelectedItem свойство класса MyViewModel не использует интерфейс INotifyPropertyChanged, поднимая событие PropertyChanged когда связующий изменен его значение:

public Item SelectedItem 
{ 
    get { return _selectedItem; } 
    set 
    { 
     if(value != _selectedItem) 
     { 
      _selectedItem= value; 
      OnPropertyChanged("SelectedItem"); 
     } 
    } 
} 

Вы должны сделать это для всех объектов во всех ViewModels.

+0

Я сделал это, но это не сработало. Я не устанавливаю SelectedItem через код. Я выбираю действие через представление. И при нажатии на действие сеттер не вызывается. –

3

Необходимо указать привязку TwoWay на выбранном элементе. В противном случае изменения, внесенные в пользовательский интерфейс, не передаются в вашу модель просмотра.

SelectedItem="{Binding SelectedAction, Mode=TwoWay}" 
+0

Пробовал, что не работает. Он отлично подходит для SelectedItem в классе ViewModel. Но не работает во внутреннем списке. –

+0

Внутренний список не зависит от измененного свойства или наблюдаемого коллекционирования. Таким образом, вы не видите никаких изменений во внутреннем списке. – Xelom

0

Я не знаю, если я на правильном пути, но вы пытались обернуть свою строку в классе?

public class Item : INotifyOfPropertyChanged 
{ 
public string Name; 

private ObservableCollection<MyActionString> _actions; 
public ObservableCollection<MyActionString> Actions 
{ 
    get { return _actions?? (_actions= new ObservableCollection<MyActionString>); } 
} 

private MyActionString _selectedAction; 
public MyActionString SelectedAction 
{ 
    get { return _selectedAction; } 
    set { _selectedAction = value; } 
} 
} 
+0

Я тоже пробовал это, но нет, он не работает. –

5

Я не знаю, если это ваш случай, но так как вы сказали, что вы вырезали какую-то информацию, я постараюсь ответить.

это случается со мной, когда я добавляю шаблон custum в ListBox или ListView и что элементы управления в ListBoxItem обрабатывают событие clicksselve.

Например, если у вас есть переключатель, как этот

<ListBox ItemsSource="{Binding List}" SelectedItem="{Binding item}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <RadioButton Content="{Binding Name}" GroupName="groupName"> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

SelectedItem не будет установлен, когда вы actualy нажмите на кнопку радио, потому что радио-кнопка будет обрабатывать событие щелчка и не будет пузырем его поэтому ListBox может изменить его выбор.

Вы должны убедиться, что ListBox получает событие и что элементы управления в шаблоне реагируют соответствующим образом. в этом случае вам придется сделать что-то подобное.

<ListBox ItemsSource="{Binding List}" SelectedItem="{Binding Item}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <RadioButton Content="{Binding Name}" IsHitTestVisible="False"> 
     <RadioButton.Style> 
      <Style TargetType="{x:Type RadioButton}"> 
      <Setter Property="IsChecked" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" /> 
      </Style> 
     </RadioButton.Style> 
     </RadioButton> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
0

Посмотрите в окно вывода в VS. Вероятно, ваш тип свойства отличается от типа элемента.

0

Неверный ответ «Erno de Weerd», вы должны уведомить об изменении свойства по выбранным вами свойствам, но также и WPF DataGrid - это самый прослушиваемый элемент управления, предлагаемый Microsoft в отношении MVVM.

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

SelectedItem = «{Binding SelectedAction, UpdateSourceTrigger = PropertyChanged

Это не требуется когда список не встроен в столбец datagrid.

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