Même après avoir examiné une multitude de propositions de solution, je ne peux pas obtenir une simple liaison bidirectionnelle dans xaml pour fonctionner. J'ai une fenêtre, un dataContext et une application. A) pendant l'exécution du constructeur de l'application, la fenêtre (initialisée et .Show
-d dans le même constructeur) apparaît, mais n'est pas mise à jour du tout, même si je bascule la valeur de la case à cocher dans mon code C# quelques fois; B) lorsque le constructeur de l'application a fini, la fenêtre est mise à jour exactement une fois; Je l'ai configuré de sorte que si je clique sur la case à cocher dans la fenêtre, le gestionnaire d'événements dans App (lié à la notification de changement de propriété DataContext) devrait augmenter la taille d'une liste de chaînes, qui est également affichée. L'augmentation de la liste se produit correctement dans le code, mais n'est pas reflétée dans la fenêtre.Liaison bidirectionnelle WPF ne fonctionnant pas sur CheckBox et la liste <string>
Résumé:
- entrée utilisateur dans la fenêtre atteins le code C# App bien: je peux agir sur les changements de case à cocher, etc.
- le sens inverse ne fonctionne pas: chaque fois que les éléments sont modifiés DataContext via le code, la fenêtre n'est pas automatiquement mise à jour, même si iNotifyProperty est implémenté et exécuté.
Ce que je me attends est que:
a) pendant le fonctionnement du constructeur App et permet de basculer la valeur CheckBox, la fenêtre doit tenir compte des changements de réglage/compensation de la tique sur la boîte; B) une fois le constructeur de l'application terminé, chaque fois que je passe de CheckBox de FALSE à TRUE, le NameList
est ajouté avec une nouvelle chaîne. Je m'attendrais à ce que la liste dans la fenêtre augmente en conséquence et affiche automatiquement le contenu NameList
complet et ajouté.
Observations:
- j'essaie de faire en sorte que le DataContext sur la fenêtre est réglée avant d'appeler
InitializeComponent
sur la fenêtre. Ne fait pas vraiment une différence, malheureusement ... - je reçois un indice unique dans VS dans le fichier MainWindow.xaml: le chemin CheckBox ainsi que la liaison ListBox
NameList
sont annotés avecCannot resolve symbol due to unknown DataContext
Cependant, lorsque l'application constructeur termine la fenêtre est mis à jour et lorsque je clique sur le CheckBox, l'événement NotifyProperty correct est déclenché. Cela me dit que les liaisons d'exécution devraient fonctionner ... apparemment seulement à sens unique, pas à deux voies cependant.
MainWindow.xaml:
<Window x:Class="StatisticsEvaluation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Vertical">
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="CheckBox" />
<ListBox ItemsSource="{Binding NameList, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock FontSize="18" FontFamily="Arial" Foreground="Black" Text="TextBlock" Visibility="Visible" />
</StackPanel>
</Grid>
MainWindow.xaml.cs:
namespace StatisticsEvaluation
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
}
}
}
L'application et DataContext:
namespace StatisticsEvaluation
{
public class DataContextClass : INotifyPropertyChanged
{
private bool isChecked;
public bool IsChecked
{
get
{
return isChecked;
}
set
{
isChecked = value;
OnPropertyChanged("IsChecked");
}
}
private List<string> nameList;
public List<string> NameList
{
get
{
return nameList;
}
set
{
nameList = value;
OnPropertyChanged("NameList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private MainWindow MyWindow { get; set; }
private DataContextClass MyDataContext{ get; set; }
private void HandleDataContextPropertyChange(object sender, PropertyChangedEventArgs e)
{
// If the CheckBox was just toggled to TRUE, increase the NameList
// with an additional name and call OnPropertyChanged on it ...
// hoping that this would trigger a Window UI update - but no luck !
if ((e.PropertyName == "IsChecked") && MyDataContext.IsChecked)
{
var randomProvider = new Random();
MyDataContext.NameList.Add(randomProvider.Next().ToString());
MyDataContext.OnPropertyChanged("NameList");
}
}
public App()
{
MyDataContext = new DataContextClass();
MyDataContext.PropertyChanged += HandleDataContextPropertyChange;
MyWindow = new MainWindow {DataContext = MyDataContext};
MyWindow.InitializeComponent();
MyWindow.Show();
MyDataContext.NameList = new List<string>();
MyDataContext.NameList.Add("FirstName");
MyDataContext.NameList.Add("SecondName");
MyDataContext.NameList.Add("ThirdName");
MyDataContext.IsChecked = true;
Thread.Sleep(3000);
MyDataContext.IsChecked = false;
Thread.Sleep(3000);
MyDataContext.IsChecked = true;
}
}
}
Quand je commence l'application de la fenêtre suivante apparaît, une fois que le constructeur App frappe .Show
:
Une fois le constructeur de l'appli h comme terminée, la fenêtre est mis à jour une fois, mais jamais plus tard, quel que soit le nombre de chaînes sont ajoutées à NameList
:
Toutes les idées, pourquoi mes deux sens de liaison ne fonctionne que dans un sens?
Je vous suggère de supprimer tout ce bizarre choses '' dans MyDataContext' de app' et juste créer le viewmodel dans le constructeur MainWindow ou quelque chose. En outre, utilisez toujours 'ObservableCollection' pour les collections qui seront liées aux contrôles dans WPF. Ne pas utiliser la liste. Il ne déclenche pas d'événements lorsque son contenu change. –
'ItemsSource =" {Lister NameList, Mode = TwoWay} "' n'a pas de sens.Un ItemsControl ne change jamais sa propriété 'ItemsSource', de sorte que le réglage' Mode = TwoWay' n'a jamais d'effet. En outre, 'MyDataContext.OnPropertyChanged (" NameList ");' est ignoré silencieusement car l'instance NameList ne change pas. Utilisez donc une ObservableCollection. – Clemens
Messieurs - merci! En effet, mon erreur principale était de ne pas utiliser une ObservableCollection. J'ai également enlevé le 'Mode = TwoWay' sur la liaison NameList et - comme vous l'avez mentionné, Clemens - il n'avait en effet aucun effet (et fonctionnait parfaitement sans que le mode TwoWay ne soit explicitement défini). Merci d'avoir fait remarquer cela. Ed, je vais essayer la création de viewmodel dans MainWindow. Mon code pour l'instant était plus un contrôle de faisabilité pour moi-même. Cela (et mes connaissances limitées WPF) ont conduit à la structure inhabituelle. Je vais corriger cela. – Woelund