Verständnis der WPF-Datenbindung und Wert Konverter Interaktionen

Ich versuche zu verstehen, was wirklich geschieht hinter den kulissen auf die vereinfachte repro-code unten.

Habe ich eine einzelne Window mit einem ListBox und ein TextBlock gebunden sind, zusammen (D. H., master -> Details). Dann habe ich ein ViewModel mit ein paar Eigenschaften--einen string und ein Datum. Für die Datum, ich implementiert eine Wert-Konverter (LongDateConverter).

Habe ich ein paar Debug.WriteLine() - Aufrufe im code, führt zu der folgenden Ausgabe:

  • App starten
    • In converter: ConverterProblem.MainWindowViewModel
    • In converter: null
  • Klicken Sie auf eines der beiden Elemente in der Liste
    • In converter: ConverterProblem.DataModel

Den zweiten und Dritten fordert, um die IValueConverter Methode, die ich glaube, ich verstehe. Die zweite ist null weil die ListBox nicht über ein ausgewähltes Element noch. Die Dritte ist für das Element, dass ich ausgewählt.

Was ich nicht verstehe ist:

  1. Warum ist der erste Aufruf als Wert übergeben, der vom Typ MainWindowViewModel?
  2. Warum ist das auch passiert in den ersten Platz?

Hier ist mein 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();
        }
    }
}
Verwenden Sie MVVMLight, oder Ihre eigenen MVVM?
meine eigenen. Die code, die ich gemeinsam in einem Vanille-WPF-app ist alles dort ist zu ihm.
Es wird schwieriger sein, um herauszufinden, ohne zu sehen, den code. Es muss einen Grund, warum Ihr Konverter erhält MainWindowViewModel in der ersten iteration. Sie ordnen Daten Kontext-überall?
Zeigen Sie uns, wo und wie Ihr Blick bekommt, "in Verbindung" zu deinem viewmodel. Fügen Sie den code in Frage zu stellen bitte.
Eigentlich wollte ich das teilen des Codes. 🙂 Es war die Verbindung im MainWindow-Konstruktor und auch im TextBlock. Was Rohit teilte in seiner Antwort stellte sich als das heraus, was mir fehlte. Danke für die Hilfe, obwohl, Jungs.

InformationsquelleAutor GusP | 2014-07-10

Schreibe einen Kommentar