/ Ligação de Dados / MVP do WPF Aninhado do DataGrid - wpf, ligação de dados

Ligação de Dados MVP do WPF DataGrid Aninhado - wpf, ligação de dados

Eu sou um iniciante ao padrão WPF e MVVM. Eu ainda tenho um problema com ligação de dados em caso de ligação inversa. Eu gostaria de vincular selectedValues ​​das caixas de combinação em minha coleção Oberservable. Eu aprendi que é possível vincular o valor de uma caixa de combinação a uma propriedade, mas, neste caso, gostaria de vincular a uma propriedade de uma coleção e a coleção é o pai.

Alguém poderia me explicar como ligar os valores selecionados da combobox à minha observação?

Eu tenho uma solução em minha mente para fazer para cadacombobox uma nova propriedade no meu viewmodel e coletar todos os valores e armazenar pelo botão pressionar esses valores em minha coleção, mas isso me parece errado, porque não é o comportamento de ligação de dados.

EDITAR Os itens da caixa de combinação são corrigidos preenchidos de cada modelo, mas como posso vincular o valor selecionado da caixa de combinação à minha propriedade de coleção?

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Path=DataContext.Cities}"
DisplayMemberPath="Name"
SelectedValue="{Binding Path=RowEntries }"/>

The SelectedValue="{Binding Path=RowEntries}" está errado ou está correto?

EDIT 2

Eu adicionei um ListView vinculado à minha coleção para ver, se as propriedades são vinculadas ao valor selecionado da minha caixa de combinação, mas é mantido vazio.

<ListView ItemsSource="{Binding RowEntries}" BorderBrush="Black" BorderThickness="1">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CityName}"></TextBlock>
<TextBlock Text="{Binding Path=CountryName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Eu tenho essa solução:

Solução

Meus modelos:

// INPC implemented by Propertychanged.Fody
public class RowEntry : BaseModel
{
public string CityName { get; set; }
public string CountryName { get; set; }
}

// INPC implemented by Propertychanged.Fody
public class City : BaseModel
{
public string Name { get; set; }
}
// INPC implemented by Propertychanged.Fody
public class Country : BaseModel
{
public string Name { get; set; }
}

Meu ViewModel:

public class TestViewModel : ViewModelBase
{
#region properties
// INPC implemented by Propertychanged.Fody
public ObservableCollection<City> Cities { get; set; } = new ObservableCollection<City>();
public ObservableCollection<Country> Countries { get; set; } = new ObservableCollection<Country>();
public ObservableCollection<RowEntry> RowEntries { get; set; } = new ObservableCollection<RowEntry>();
#endregion

#region constructors and destructors

/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public TestViewModel()
{
// Sample Data
var temp = new City { Name = "Rom" };
Cities.Add(temp);
var temp2 = new City { Name = "Sydney" };
Cities.Add(temp2);

var temp3 = new Country { Name = "Italy" };
Countries.Add(temp3);
var temp4 = new Country { Name = "Australia" };
Countries.Add(temp4);

RowEntries.Add(new RowEntry());
}
#endregion
}

Meu ui:

<StackPanel>
<DataGrid ItemsSource="{Binding RowEntries}" AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Header="#"/>
<DataGridTemplateColumn Header="City">
<DataGridTemplateColumn.CellTemplate>
<HierarchicalDataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Path=DataContext.Cities}"
DisplayMemberPath="Name"
SelectedValue="{Binding Path=RowEntries }"/>
</HierarchicalDataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Countries">
<DataGridTemplateColumn.CellTemplate>
<HierarchicalDataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},
Path=DataContext.Countries}"
DisplayMemberPath="Name"/>
</HierarchicalDataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="Add Row" Margin="0,0,1797,0"></Button>
</StackPanel>

Respostas:

1 para resposta № 1

Você deve ligar a propriedade SelectedValue doComboBoxes para as propriedades CityName e CountryName do objeto RowEntry e defina a propriedade SelectedValuePath dos ComboBoxes como "Nome". Também defina o UpdateSourcePropertyTrigger das ligações para PropertyChanged:

<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Header="#"/>
<DataGridTemplateColumn Header="City">
<DataGridTemplateColumn.CellTemplate>
<HierarchicalDataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Cities}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=CityName, UpdateSourceTrigger=PropertyChanged}"/>
</HierarchicalDataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Countries">
<DataGridTemplateColumn.CellTemplate>
<HierarchicalDataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Countries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=CountryName, UpdateSourceTrigger=PropertyChanged}"/>
</HierarchicalDataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>

Em seguida, os setters das propriedades de origem (CityName e CountryName) serão chamados quando você selecionar um item nos ComboBoxes.

Se você quiser selecionar alguns valores inicialmente, basta definir essas propriedades para alguns valores que estão presentes nas caixas de combinação:

public TestViewModel()
{
...
RowEntries.Add(new RowEntry() { CityName = "Sydney", CountryName = "Australia" });
}