我在一个新的 WPF 应用程序中使用 BackgroundWorker,我需要在它在后台工作时报告进度/更新 UI。
我在 WIndows Forms 应用程序中已经这样做了很长时间。我刚刚为 WPF 重写了这一切,这让我有点头疼。
它在运行时不断抛出以下错误:
System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=5046349)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=5046349); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=5046349)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=5046349); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=6619237)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=6619237); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=6619237)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=6619237); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=7536755)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=7536755); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=7536755)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=7536755); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=7536755)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=7536755); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=7536755)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=7536755); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=6357089)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=6357089); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=6357089)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=6357089); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=6750311)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=6750311); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=6750311)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=6750311); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=6619237)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=6619237); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') System.Windows.Data Error: 40 : BindingExpression path error: 'Subject' property not found on 'object' ''Char' (HashCode=6619237)'. BindingExpression:Path=Subject; DataItem='Char' (HashCode=6619237); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
我不知道这到底是什么意思。一些 Google 搜索没有显示任何有帮助的内容。
我还要指出,如果我不在 WPF 中使用 BGWorker,代码实际上确实可以很好地检索所有邮件。但是当我使用后台 worker 时它只会停止工作并停止绑定(bind)。我不知道为什么。 完全相同的代码适用于 BGWorker 的 WinForms。
此错误的真正含义是什么?我该怎么做才能摆脱它?
代码隐藏:
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>
最佳答案
这是一个数据绑定(bind)错误
阅读这些内容的最简单方法是用冒号/分号将其分开,然后向后阅读
System.Windows.Data Error: 40 : BindingExpression path error: 'Sender' property not found on 'object' ''Char' (HashCode=6619237)'. BindingExpression:Path=Sender; DataItem='Char' (HashCode=6619237); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
- 目标属性是“文本”(类型“字符串”)
- 目标元素是 'TextBlock' (Name='');
- BindingExpression:Path=Sender;
- DataItem='Char' (哈希码=6619237);
- 在“对象”“Char”(HashCode=6619237) 上未找到“Sender”属性。
- BindingExpression路径错误:
- System.Windows.Data 错误:40:
1 告诉你有一个 Text
属性导致了错误
2 告诉您 Text 属性在 <TextBlock>
元素上
3 告诉你导致问题的binding express是{Binding Path=Sender}
4告诉你<TextBlock>
元素后面的DataItem/DataContext是Char
数据类型的item
5 告诉你实际的问题:Sender
类型的对象上没有名为 Char
的属性
6 只是告诉你这是一个绑定(bind)错误
因为我看到你的 Sender
类上有一个名为 Message
的公共(public)属性,而且很明显 Message
不是 Char
,很明显你的每个项目的 DataContext
都是错误的。
因为它被设置为 Char
,最可能的原因是您绑定(bind)到一个字符串,并且每个元素的 DataContext
是该字符串中的一个字符。
果然, ItemsSource="{Binding Source=Messages}
意味着您正在将绑定(bind)的 Source
属性从当前的 DataContext
更改为 string
。而字符串只是字符数组,所以这意味着你绑定(bind)到字符数组 { M, e, s, s, a, g, e, s }
如果您将 Source
属性更改为 Path
属性,那么它将正确读取 DataContext.Messages
,并且应该可以工作。
<ListView ItemsSource="{Binding Path=Messages}" ... />
(此处的 Path
一词是可选的,因为如果您不指定属性名称,那么绑定(bind)会假定它是 Path
属性的值)
附带说明一下,我没有看到您在表单的任何位置设置
DataContext
,我也没有看到公共(public) Messages
属性。
MainWindow
构造函数应该有一行代码,看起来像这样将 DataContext
设置为它自己:
this.DataContext = this;
您可能需要为您的 ObservableCollection<Message> messages
设置一个公共(public)属性,以便 ListView
绑定(bind)可以找到它:
public ObservableCollection<Message> Messages
{
get { return messages; }
set { messages = value; }
}
我不确定这些是否只是被忽略了,或者您是否不知道自己需要它们。
哦,如果您计划更改任何这些绑定(bind)属性并让 UI 自动更新,您也需要实现 INotifyPropertyChanged :)
因为我在这里处于教程模式,所以我想我也应该链接到这个答案:
如果您不了解 WPF 的工作原理并且要从 Winforms 切换到 WPF,我强烈建议通读它(以及链接的文章)。听起来像你:)
关于c# - 在 'object' 上找不到 WPF/XAML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24558379/