J'ai eu quelques problèmes pour obtenir une liste de sélection pour lier correctement une collection.La propriété n'est pas liée correctement dans ListBox DataTemplate
Je vais donner le code cadre, puis expliquer ce que je veux qu'il fasse.
XAML Markup:
<ListBox DataContext="{Binding Foos, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding Main.SelectedFoo, Mode=TwoWay,
Source={StaticResource Locator},
UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding Main.SelectedFoo, Source={StaticResource Locator}}"/>
<ListBox ItemsSource="{Binding Main.SelectedFoo.Bars}" SelectedItem="{Binding Main.SelectedBar}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Right">
<!-- The binding requires "{Binding .}" because a path must be explicitly set for Two-Way binding,
even though {Binding .} is supposed to be identical to {Binding} -->
<TextBox Text="{Binding Path=. , UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
C# ViewModel:
private ObservableCollection<Foo> _barList = new ObservableCollection<Foo>();
private const string BardListPN = "FooList";
public ObservableCollection<Foo> FooList
{
get { return _fooList; }
set
{
if (_fooList == value)
{
return;
}
var oldValue = _fooList;
_fooList = value;
RaisePropertyChanged(FooListPN);
}
}
private Foo _selectedFoo;
private const string SelectedFooPN = "SelectedFoo";
public Foo SelectedFoo
{
get { return _selectedFoo; }
set
{
if (_selectedFoo == value)
{
return;
}
var oldValue = _selectedFoo;
_selectedFoo = value;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedFooPN);
}
}
public const string SelectedBarPN = "SelectedBar";
private string _selectedBar = "";
public string SelectedBar
{
get
{
return _selectedBar;
}
set
{
if (_selectedBar == value)
{
return;
}
var oldValue = _selectedBar;
_selectedBar = value;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedBarPN);
}
}
C# Modèle:
public class Foo
{
public ICollection<string> Bars
{
get { return _bars; }
set
{
_bars= value;
NotifyPropertyChanged("Bars");
// snipped obvious INotifyPropertyChanged boilerplate code
}
}
}
Mon problème est que les modifications apportées aux zones de texte pour les chaînes de la collection Bar
ne sont pas définies. Lorsque les Foo
sélectionnés sont remplacés par des Foo
et vice versa, les Bars
d'origine s'affichent.
Quelqu'un pourrait-il me dire ce que je fais mal? Cela semble être beaucoup plus simple. Merci! Mise à jour: J'ai modifié le code selon la suggestion de Tri Q, mais les modifications apportées à la zone de texte ne sont pas répercutées dans la propriété elle-même. Des idées?
Superbe réponse! Merci beaucoup pour l'info supplémentaire. Oui, comme vous pouvez le voir clairement, j'apprends toujours WPF et MVVM, et j'apprécie sincèrement les commentaires. Je vais essayer votre suggestion. – llaughlin
Une chose à noter: la façon dont j'ai le 'TextBox' lié, un chemin est nécessaire parce que le mode est' TwoWay' (même par défaut), et je l'ai noté dans mes commentaires XAML. Cela semble être le seul moyen d'avoir le 'TextBox' lié à l'élément actuel dans la collection. – llaughlin