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:
- Warum ist der erste Aufruf als Wert übergeben, der vom Typ
MainWindowViewModel
? - 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();
}
}
}
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Problem ist, Sie haben gebunden
Text
Abhängigkeit vor der EinstellungDataContext
für TextBlock.XAML-Dateien sind kompiliert in BAML und auf Anwendung ausführen, es ist geladen von BAML von
XAMLLoader
die Parsen der XAML-von oben nach unten und legen Sie als Wert für DP ' s entsprechend.Da, Text-DP bekommt zuerst Gefundene, so wird es versuchen, den ersten Satz ist es Wert und der DataContext ist nicht festgelegt noch für den TextBlock so wird es von seinem übergeordneten Element Erben Fenster, dessen DataContext gesetzt ist MainWindowViewModel. Also, Sie sehen, MainWindowViewModel gedruckt in Ihrem Konverter. Und als DataContext gesetzt ist, werden alle DP-s-Bindung wird neu bewertet werden als pro neuen DataContext.
Ersetzen Sie Ihre XAML, um diese und Sie werden sehen,
MainWindowViewModel
nicht drucken mehr:Ausgabe:
InformationsquelleAutor Rohit Vats