La compréhension de la liaison de données WPF et de la valeur convertisseur interactions

J'essaie de comprendre ce qui se passe réellement derrière les scènes sur la simplification de la repro de code ci-dessous.

J'ai un seul Window avec un ListBox et un TextBlock qui sont liés entre eux (c'est à dire, maître -> détail). J'ai alors d'un ViewModel avec un couple de propriétés--une chaîne de caractères et une date. Pour la date, j'ai mis en place un convertisseur de valeurs (LongDateConverter).

J'ai un couple Debug.WriteLine() appels dans le code qui mènent à la sortie suivante:

  • Lancer l'application
    • In converter: ConverterProblem.MainWindowViewModel
    • In converter: null
  • Cliquez sur l'un des deux éléments dans la zone de liste
    • In converter: ConverterProblem.DataModel

Les deuxième et troisième appels à la IValueConverter méthode, je crois que je comprends. La deuxième est null parce que le ListBox ne dispose pas d'un élément sélectionné encore. La troisième est l'article que j'ai sélectionné.

Ce que je ne comprends pas, c'est:

  1. Pourquoi le premier appel passé d'une valeur de type MainWindowViewModel?
  2. Pourquoi est-ce que l'appel même en premier lieu?

Voici mon code:

MainWindow.xaml:

<Window x:Class="ConverterProblem.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:ConverterProblem"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <app:LongDateConverter x:Key="longDateConverter"/>
    </Window.Resources>
    <StackPanel Orientation="Horizontal">
        <ListBox SelectedItem="{Binding Data}" ItemsSource="{Binding DataList}"
                 DisplayMemberPath="Name"/>
        <TextBlock Text="{Binding Converter={StaticResource longDateConverter}}" 
                   DataContext="{Binding Data}" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace ConverterProblem 
{
public class LongDateConverter : IValueConverter 
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{
if (value == null) {
Debug.WriteLine("In converter: null");
return "null";
}
Debug.WriteLine("In converter: " + value.GetType().ToString());
if (value.GetType() == typeof(MainWindowViewModel))
return "viewmodel";
return ((DataModel)value).Date.ToLongDateString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
public class DataModel
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
public class MainWindowViewModel : INotifyPropertyChanged
{
private DataModel _data;
private List<DataModel> _dataList;
public MainWindowViewModel()
{
_dataList = new List<DataModel> { 
new DataModel { Date = DateTime.Now, Name = "John" }, 
new DataModel { Date = DateTime.Now.AddDays(50), Name = "Sue" }
};
}
public DataModel Data
{
get { return _data; }
set
{
if (_data == value) return;
_data = value;
RaisePropertyChanged("Data");
}
}
public List<DataModel> DataList
{
get { return _dataList; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public partial class MainWindow : Window
{
private MainWindowViewModel _viewModel;
public MainWindow()
{
_viewModel = new MainWindowViewModel();
DataContext = _viewModel;
InitializeComponent();
}
}
}
Êtes-vous à l'aide de MVVMLight, ou votre propre MVVM?
mon propre. Le code que j'ai partagé dans une vanille application WPF est tout là est à lui.
Il sera plus difficile de comprendre sans voir le code. Il doit y avoir une raison pourquoi votre convertisseur reçoit MainWindowViewModel dans la première itération. Attribuez-vous le contexte des données de n'importe où?
Nous montrer où et comment votre vue est "connecté" à votre viewmodel. Ajoutez le code à la question s'il vous plaît.
J'ai fait part de tout le code. 🙂 Il a été la connexion dans MainWindow du constructeur et aussi dans le TextBlock. Ce Rohit partagé sa réponse s'est avéré être ce que j'étais en manque. Merci pour les aider à bien, les gars.

OriginalL'auteur GusP | 2014-07-10