Привязать сетку данных к одной ViewModel, столбец / комбинированный список к другому - PullRequest
0 голосов
/ 29 июля 2011

У меня есть View Players, для набора данных установлен ObservableCollection Players из ViewModel MainPlayerViewModel.

В представлении у меня есть сетка данных со столбцами TeamId, Name и Position.Я хочу связать столбец TeamId с помощью комбинированного списка со списком доступных команд из MainTeamViewModel, у которого есть свойство коллекции Teams, но, конечно, я хочу, чтобы MainPlayerViewModel обновлялся всякий раз, когда я обновляю команду для игрока.

Я надеюсь, что вы можете следовать за мной здесь .. Это мой xaml:

<data:DataGridTemplateColumn.CellEditingTemplate>
  <DataTemplate>
   <ComboBox DataContext="{Binding MainTeam, Mode=OneWay, Source={StaticResource Locator}}" 
    Height="23" HorizontalAlignment="Left" 
    Name="cmbTeams" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Teams, 
    Mode=TwoWay}" SelectedValue="{Binding Path=Model.teamid, Mode=TwoWay}"   
    DisplayMemberPath="Model.teamid"/>
  </DataTemplate>
 </data:DataGridTemplateColumn.CellEditingTemplate>

Когда я редактирую ячейку, она показывает список доступных команд, но выбранное значение, которое я выбираю из списка, не появляется вКолонка TeamId

Как мне это сделать?

С уважением,

Майк

ОБНОВЛЕНИЕ: Несмотря на полученную помощьЯ не работал, связывая один вид с двумя разными моделями представления.Полагаю, предлагаемое решение уже давно у меня над головой ... Я не мог установить текст данных для сетки данных в MainTeam, потому что у него есть ItemsSource игроков и выбранный элемент, привязанный к выбранному игроку.В любом случае, я решил оставить его 1 View / 1 ViewModel и создал в моем PlayerViewModel открытое свойство с именем teamVM:

    public MainTeamViewModel teamsVM
    {
       get
       {
           return ViewModelLocator.Container.Resolve<MainTeamViewModel>();
       }
    }

Теперь я могу установить для Itemource это новое свойство, и строка моего игрока обновляется при изменениикоманды:

    <DataTemplate>
     <ComboBox 
       Height="23" HorizontalAlignment="Left" 
       Name="cmbTeams" VerticalAlignment="Top" Width="100" 
       ItemsSource="{Binding teamsVM.Teams, 
       Mode=TwoWay}" SelectedValue="{Binding Model.teamid, Mode=TwoWay}"   
       DisplayMemberPath="Model.teamid" SelectedValuePath="Model.teamid"/>
    </DataTemplate>

С уважением,

Майк

Ответы [ 2 ]

0 голосов
/ 31 июля 2011

Две проблемы здесь:

  • Во-первых, как заметил @bleepzer, вы не указали пути значения / отображения в поле со списком.
  • Во-вторых, вы пытаетесь получить доступ к свойству в контексте данных, который находится за пределами вашей сетки (то есть в контексте данных модели основного представления) из шаблона данных. В silverlight 4 нет относительной привязки к источнику (то, что вы использовали бы в SL 5 или WPF), поэтому вам придется использовать привязку элементов для архивирования того, что вы хотите.

Вот пример, основанный на вашем коде. Он не завершен, поскольку не учитывает некоторые необходимые элементы DataGrid, но показывает концепцию:

<data:DataGrid x:Name="myDataGrid" 
               DataContext="{Binding MainTeam, Mode=OneWay, Source={StaticResource Locator}}" >
  <!-- additional stuff needed here -->
    <data:DataGridTemplateColumn.CellEditingTemplate>
      <DataTemplate>
        <ComboBox Height="23" HorizontalAlignment="Left" 
                  Name="cmbTeams" VerticalAlignment="Top" Width="100" 
                  ItemsSource="{Binding ElementName=myDataGrid, Path=DataContext.Teams}" 
                  SelectedValuePath="TeamId"
                  DisplayMemberPath="TeamName"
                  SelectedValue="{Binding Path=Model.teamid, Mode=TwoWay}"/>
      </DataTemplate>
    </data:DataGridTemplateColumn.CellEditingTemplate>
  <!-- additional stuff needed here -->
<data:DataGrid>

А вот и описание:

  1. Добавьте имя в вашу сетку данных.
  2. Убедитесь, что сетка данных имеет правильный контекст данных, либо установив его явно, как в примере, либо унаследовав его от родительской иерархии.
  3. Измените свойство ComboBox ItemsSource, чтобы оно указывало на сетку данных, используя имя элемента, которое вы указали ранее. Поскольку вы сейчас находитесь в элементе, а не в контексте данных, вы должны использовать DataContex.Teams для доступа к свойству Teams в контексте данных вашей сетки. ItemsSource не требует двусторонней привязки, так как представление ничего не записывает в вашу модель представления.
  4. Укажите свойства SelectedValuePath и DisplayMemberPath.
  5. Наконец, свяжите свойство SelectedValue поля со списком со свойством модели строк TeamId, используя двустороннее связывание - необходимо сейчас, так как представление должно обновлять значение модели. Важно : свойство SelectedValue поля со списком должно быть связано после с ItemsSource, чтобы избежать некоторых проблем со списком.
0 голосов
/ 29 июля 2011

Я нахожу две вещи неправильными с этим кодом.

Вам не хватает SelectedValuePath для ComboBox.Даже если вы привяжете к нему все команды, идентификатор выбранного элемента будет нулевым, поскольку SelectedValuePath отсутствует.

У вас также есть DataContext и ItemsSource.Используйте только ItemsSource для команд, которые вы хотите отобразить, и SelectedValue для привязки к teamId игрока, если только ваша модель представления не имеет свойства «Команды» и свойства «Игрок», в этом случае может использоваться DataContext.(Хотя я установил DataContext в коде ...)

Так что в итоге вы получите что-то вроде этого:

ItemsSource="{Binding Teams, Mode=TwoWay}"                  //Bind to all teams.
SelectedValue="{Binding Player, Path=TeamId, Mode=TwoWay}"  //Bind to the teamId of the player.
DisplayMemberPath="TeamName"                                //that's the Name of each team.
SelectedValuePath="TeamId"                                  //that's the Id of the team.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...