WPF/XAML-Eigenschaft nicht auf "Objekt"
Ich bin mit einem BackgroundWorker in einem neuen WPF-Anwendung und ich benötige den Fortschritt melden/aktualisieren der Benutzeroberfläche, wie es funktioniert im hintergrund.
Ich habe das getan, für eine lange Zeit in WIndows Forms-Anwendungen. Ich habe nur umgeschrieben, es sind alle für WPF-und es ist mir ein bisschen Kopfschmerzen.
Es hält werfen die folgende Fehlermeldung zur Laufzeit:
System.Windows.Daten, Fehler: 40 : BindingExpression Pfad-Fehler: 'Absender'
Eigenschaft nicht gefunden '- Objekt' "Char" (HashCode=5046349)'.
BindingExpression:Path=Absender; DataItem='Char' (HashCode=5046349);
target-element 'TextBlock' (Name="); target-Eigenschaft ist "Text"
(Typ 'String') System.Windows.Daten, Fehler: 40 : BindingExpression Weg
Fehler: 'Subjekt' - Eigenschaft nicht auf "Objekt" "Char"
(HashCode=5046349)'. BindingExpression:Path=Thema; DataItem='Char'
(HashCode=5046349); target element 'TextBlock' (Name="); target
Eigenschaft 'Text' (Typ 'String') System.Windows.Daten, Fehler: 40 :
BindingExpression Pfad-Fehler: 'Absender' Eigenschaft nicht gefunden '- Objekt'
"Char" (HashCode=6619237)'. BindingExpression:Path=Absender;
DataItem='Char' (HashCode=6619237); target element 'TextBlock'
(Name="); target-Eigenschaft 'Text' (Typ 'String')
System.Windows.Daten, Fehler: 40 : BindingExpression Pfad Fehler:
'Subjekt' Eigenschaft nicht gefunden '- Objekt' "Char" (HashCode=6619237)'.
BindingExpression:Path=Thema; DataItem='Char' (HashCode=6619237);
target-element 'TextBlock' (Name="); target-Eigenschaft ist "Text"
(Typ 'String') System.Windows.Daten, Fehler: 40 : BindingExpression Weg
Fehler: 'Absender' Eigenschaft nicht gefunden '- Objekt' "Char"
(HashCode=7536755)'. BindingExpression:Path=Absender; DataItem='Char'
(HashCode=7536755); target element 'TextBlock' (Name="); target
Eigenschaft 'Text' (Typ 'String') System.Windows.Daten, Fehler: 40 :
BindingExpression Pfad-Fehler: 'Subjekt' - Eigenschaft nicht auf "Objekt"
"Char" (HashCode=7536755)'. BindingExpression:Path=Thema;
DataItem='Char' (HashCode=7536755); target element 'TextBlock'
(Name="); target-Eigenschaft 'Text' (Typ 'String')
System.Windows.Daten, Fehler: 40 : BindingExpression Pfad-Fehler: 'Absender'
Eigenschaft nicht gefunden '- Objekt' "Char" (HashCode=7536755)'.
BindingExpression:Path=Absender; DataItem='Char' (HashCode=7536755);
target-element 'TextBlock' (Name="); target-Eigenschaft ist "Text"
(Typ 'String') System.Windows.Daten, Fehler: 40 : BindingExpression Weg
Fehler: 'Subjekt' - Eigenschaft nicht auf "Objekt" "Char"
(HashCode=7536755)'. BindingExpression:Path=Thema; DataItem='Char'
(HashCode=7536755); target element 'TextBlock' (Name="); target
Eigenschaft 'Text' (Typ 'String') System.Windows.Daten, Fehler: 40 :
BindingExpression Pfad-Fehler: 'Absender' Eigenschaft nicht gefunden '- Objekt'
"Char" (HashCode=6357089)'. BindingExpression:Path=Absender;
DataItem='Char' (HashCode=6357089); target element 'TextBlock'
(Name="); target-Eigenschaft 'Text' (Typ 'String')
System.Windows.Daten, Fehler: 40 : BindingExpression Pfad Fehler:
'Subjekt' Eigenschaft nicht gefunden '- Objekt' "Char" (HashCode=6357089)'.
BindingExpression:Path=Thema; DataItem='Char' (HashCode=6357089);
target-element 'TextBlock' (Name="); target-Eigenschaft ist "Text"
(Typ 'String') System.Windows.Daten, Fehler: 40 : BindingExpression Weg
Fehler: 'Absender' Eigenschaft nicht gefunden '- Objekt' "Char"
(HashCode=6750311)'. BindingExpression:Path=Absender; DataItem='Char'
(HashCode=6750311); target element 'TextBlock' (Name="); target
Eigenschaft 'Text' (Typ 'String') System.Windows.Daten, Fehler: 40 :
BindingExpression Pfad-Fehler: 'Subjekt' - Eigenschaft nicht auf "Objekt"
"Char" (HashCode=6750311)'. BindingExpression:Path=Thema;
DataItem='Char' (HashCode=6750311); target element 'TextBlock'
(Name="); target-Eigenschaft 'Text' (Typ 'String')
System.Windows.Daten, Fehler: 40 : BindingExpression Pfad-Fehler: 'Absender'
Eigenschaft nicht gefunden '- Objekt' "Char" (HashCode=6619237)'.
BindingExpression:Path=Absender; DataItem='Char' (HashCode=6619237);
target-element 'TextBlock' (Name="); target-Eigenschaft ist "Text"
(Typ 'String') System.Windows.Daten, Fehler: 40 : BindingExpression Weg
Fehler: 'Subjekt' - Eigenschaft nicht auf "Objekt" "Char"
(HashCode=6619237)'. BindingExpression:Path=Thema; DataItem='Char'
(HashCode=6619237); target element 'TextBlock' (Name="); target
Eigenschaft 'Text' (Typ 'String')
Ich habe keine Ahnung, was das eigentlich bedeutet. Ein paar Google-suchen nicht zu offenbaren, etwas, das dazu beigetragen hat.
Ich werde auch darauf hinweisen, dass der code tatsächlich abgerufen werden alle mails nur in Ordnung, wenn ich nicht verwenden, die BGWorker in WPF. Aber es hält nur arbeiten und Stoppt dann verbindlich, wenn ich den hintergrund-Arbeiter. Ich habe keine Ahnung, warum. Die exakt gleiche code arbeitet in WinForms für BGWorker.
Was bedeutet dieser Fehler wirklich bedeuten und was kann ich tun, um es loszuwerden?
Code-behind:
public partial class MainWindow : Window
{
public BackgroundWorker worker = new BackgroundWorker();
public ObservableCollection<Message> messages = new ObservableCollection<Message>();
public MailMessage msg;
int count = 0;
public class Message
{
public string Sender { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
public DateTime DateReceived { get; set; }
public DateTime DateRead { get; set; }
public MailMessage Mail { get; set; }
}
public MainWindow()
{
InitializeComponent();
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
worker.DoWork += Worker_DoWork;
}
private void RetrieveMessages()
{
//Working code.
using (var imap = new AE.Net.Mail.ImapClient())
{
for(int i = 0; i < count; i++)
{
MailMessage msg = imap.GetMessage(i, true, false);
worker.ReportProgress(i);
}
}
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
if(count != 0)
RetrieveMessages();
else
{
using(var imap = new AE.Net.Mail.ImapClient())
{
count = imap.GetMessageCount("Inbox");
}
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
status.Text = "Status: Idle.";
list.ItemsSource = messages;
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine(msg.Sender.Address + " " + msg.Subject);
MessageBox.Show(msg.Subject);
if(msg != null)
{
messages.Add(new Message()
{
Sender = "hi",
Subject = msg.Subject,
Content = msg.Body,
Mail = msg
});
msg = null;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//DEBUG ONLY
worker.RunWorkerAsync();
status.Text = "Status: Synchronizing.";
}
}
XAML:
<ScrollViewer ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ListView x:Name="list" ItemsSource="{Binding Source=Message}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="{x:Null}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<TextBlock x:Name="senderLabel" Text="{Binding Sender}" HorizontalAlignment="Stretch" TextTrimming="WordEllipsis" TextWrapping="Wrap" FontWeight="SemiBold" />
<TextBlock x:Name="subjectLabel" Text="{Binding Subject}" HorizontalAlignment="Stretch" TextTrimming="WordEllipsis" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
- ändern Sie Ihre ListView-Bindung an die Sammlung: "ItemsSource="{Binding Nachrichten}"
- Ich habe es geändert von Message-Nachrichten, die in XAML, aber ich bin immer noch der gleiche Fehler angezeigt.
- überprüft es jetzt deine Einstellung nicht etwas in datacontext so eine Bindung nicht in der listview entfernen ItemsSource="{Binding Source=Message}", als es sollte arbeiten, weil Sie es im code-behind. Und sollten Sie Lesen, einige Artikel über Bindung und mvvm 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist ein DataBinding-Fehler
Einfachste Weg, um zu Lesen, diese ist Pause bis er durch den Doppelpunkt/semi-colons, und Lesen Sie es nach hinten
1 sagt Ihnen, dass es ein
Text
Eigentum verursacht die Fehler2 erzählt Sie, dass die Text-Eigenschaft ist auf eine
<TextBlock>
element3 sagt, dass Sie die Bindung express das problem verursacht
{Binding Path=Sender}
4 sagt, dass Sie die DataItem - /DataContext hinter der
<TextBlock>
element ist ein Element von Daten TypChar
5 sagt Sie das eigentliche problem dabei: es gibt keine Eigenschaft mit dem Namen
Sender
auf das Objekt vom TypChar
6 zeigt nur, dass es eine verbindliche Fehler
7 ich habe keine Ahnung, was es bedeutet
Da ich sehe, haben Sie eine öffentliche Eigenschaft mit dem Namen
Sender
auf IhreMessage
Klasse, und seine klaren, dassMessage
ist nichtChar
, seine offensichtlich, dass Sie IhreDataContext
für jedes Element ist falsch.Seit einem
Char
die wahrscheinlichste Ursache ist die Bindung an eine Zeichenfolge an, und derDataContext
für jedes element ist ein Zeichen in diesem string.Und sicher genug,
ItemsSource="{Binding Source=Messages}
heißt, Sie verändern die BindungSource
Eigenschaft aus der aktuellenDataContext
zu einemstring
. Und strings sind nur Zeichen-arrays, so dass es bedeutet, dass Sie verbindlich sind die Zeichen-array{ M, e, s, s, a, g, e, s }
Wenn Sie ändern die
Source
- Eigenschaft, um diePath
Eigenschaft, dann wird es richtig LesenDataContext.Messages
statt, und sollte funktionieren.(Das Wort
Path
hier ist optional, denn wenn Sie nicht geben Sie einen Eigenschaftsnamen dann verbindlich, vorausgesetzt es ist der Wert für diePath
Eigenschaft)Als seitliche Anmerkung, die ich nicht sehen Sie die Einstellung Ihres
DataContext
irgendwo auf der form, und ich sehe nicht ein, eine öffentlicheMessages
Eigenschaft entweder.Den
MainWindow
Konstruktor sollte wahrscheinlich eine code-Zeile, die so aussieht wie dieDataContext
zu sich selbst :Und Sie wahrscheinlich brauchen eine öffentliche Eigenschaft für Ihre
ObservableCollection<Message> messages
so dieListView
Bindung finden können :Ich bin mir nicht sicher, ob diese nur übersehen, oder wenn Sie nicht wissen, Sie Sie brauchten.
Oh, und wenn Sie plan auf das ändern dieser Eigenschaften gebunden und mit der Benutzeroberfläche automatisch aktualisiert, Sie werden wollen, zu implementieren INotifyPropertyChanged auch 🙂
Und da bin ich im tutorial-Modus hier, dachte ich, ich sollte auch den link zu dieser Antwort :
Ich würde empfehlen, das Lesen durch Sie (und die verlinkten Artikel), wenn Sie neu auf, wie WPF arbeitet und den Wechsel von Winforms zu WPF. Die es klingt wie Sie sind 🙂
string
, also ich weiß nicht warum, es sagt mir es istchar
. Ich denke, es hat etwas zu tun mit der BackgroundWorker-Klasse. Einzige Grund, warum ich denke, das ist, weil der gleiche code funktioniert gut, ohne die BGWorker. Waren Sie mit einem BackgroundWorker, wenn Sie habe diesen Fehler @Rachel?{Binding }
standardmäßig dieSource
eingestellt ist, um dieDataContext
, und diePath
eingestellt ist, um dieSource
. Wenn Sie schreibenItemsSource="{Binding Source=Messages}
ändern Sie dieSource
dieser Bindung von der aktuellenDataContext
eine Reihe von"Messages"
, und ein string ist nichts anderes als ein Zeichen-array. So sind Sie verbindlich IhreListView
auf ein Zeichen-array von{ M, e, s, s, a, g, e, s }
, und jederListViewItem
hat eineDataContext
einer der Charakterethis.DataContext = this
in den meisten Fällen, weil die Daten soll geliefert werden, wer ist mit der Kontrolle. Hardcoding es wie, der bricht die Trennung von Daten und UI, und Niederlagen einer WPF größten Vorteile "lookless-Steuerelemente". Die einzige Zeit, die es sinnvoll ist, für die Kontrollen, die dazu bestimmt sind, zu definieren und zu verwenden, Ihre eigenen Daten nur, oder beim testen.Im Gegensatz zu vielen .NET Fehler, diese bedeuten genau, was Sie sagen... alles, was Sie tun müssen, ist, Sie zu Lesen. Mit dieser als Beispiel:
Irgendwo im XAML-Code, den Sie versuchen, Daten zu binden, eine Eigenschaft mit dem Namen
Sender
zu einemTextBlock.Text
Eigenschaft... diese Informationen sind alle, die in Ihrem Fehler. Jedoch ist es weiterhin, dass das Objekt die Daten gebunden ist, ist der Typobject
und dieobject
- Klasse nicht über eine Eigenschaft namensSender
... also... Fehler.Um es zu beheben, finden Sie die
TextBlock
und dieBinding
und entweder Sie tauschen dieobject
mit einer Instanz der Klasse, die hat haben die Eigenschaft mit dem NamenSender
oder alternativ eine Immobilie zu binden, dass ist definiert in derobject
Klasse.Beurteilung durch die Anzahl dieser Fehler, den Sie haben, muss ich davon ausgehen, dass Sie wird verursacht durch eine
Binding
in einemItemTemplate
, zB. Sie haben die gleichen Fehler, die durch jedes Element der Sammlung.Wenn Sie eine
ItemsSource
Eigenschaft, es nimmt Sie auf der Durchreise sind, in einemIEnumerable
. WPF wird auch standardmäßig, vorhanden Dinge wie Ihre geben Sie name, wenn Sie nicht finden können, etwas anderes nützliches zu tun, etwas. Da string ist einIEnumerable
(von Zeichen), wird das Listenelement übergeben wird das gebundene Objekt-Typ-Namen in derItemTemplate
, da es das einzige "vernünftige" Sache, die Sie herausfinden können, zu tun. Und da der Char-Typ offenbar keinen Absender und Betreff der Eigenschaften der code geht boom.Als Beweis, vergleichen Sie die Ausgabe des folgenden code und die hashcodes in Ihrer Fehlermeldungen.
Statt mit einem
ListView
, nutzen Sie einfach das stack-panel mit datasource gleich die Nachricht, und löschen Sie die übergeordnete Steuerelemente: