2014-07-03 43 views
7

我在新的WPF应用程序中使用BackgroundWorker,我需要报告进度/更新UI,因为它在后台工作。WPF/XAML Property'not'on'object'

我在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')

我不知道什么实际意义。一些谷歌搜索没有透露任何有用的信息。

我还会指出,如果我不使用WPF中的BGWorker,代码实际上检索所有邮件就好了。但是,它只会停止工作,并在我使用后台工作时停止绑定。我不知道为什么。 完全相同的代码适用于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> 
+1

改变你的ListView绑定到Collection:的ItemsSource =“{绑定邮件}“ – Mark

+0

@Mark谢谢Mark当我回到楼梯时,我会试试这个片刻。 –

+0

@Mark,我已将它从消息更改为XAML中的消息,但我仍然显示相同的错误。 –

回答

32

这是一个数据绑定错误阅读这些

最简单的方法是打破它由冒号/分号,并读取它向后

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')

  1. 目标属性是“文本”(类型'字符串')
  2. 目标元素是'TextBlock'(Name ='');
  3. BindingExpression:Path = Sender;
  4. DataItem ='Char'(HashCode = 6619237);
  5. 在'object''Char'(HashCode = 6619237)'找不到'Sender'属性。
  6. BindingExpression路径错误:
  7. System.Windows.Data错误:40:

1告诉你,有一个Text财产造成错误

2告诉你,Text属性是一个<TextBlock>元素

3告诉你绑定快递引起的问题是{Binding Path=Sender}

4告诉你的DataItem /的DataContext <TextBlock>元素背后的数据类型为Char

5的项目会告诉你这个实际的问题:没有指定类型的对象Sender财产Char

6只告诉你这是一个绑定错误

7我有no idea what it means

因为我看到你有一个名为Sender的公共属性您Message类,它清楚地表明Message不是Char,很显然你的DataContext对于每个项目都是错误的。

由于它被设置为Char,最可能的原因是您绑定到一个字符串,并且每个元素的DataContext是该字符串中的一个字符。

当然,ItemsSource="{Binding Source=Messages}意味着您将绑定的Source属性从当前DataContext更改为string。和字符串只是字符数组,所以这意味着如果你的Source属性更改为Path属性要绑定到字符数组{ M, e, s, s, a, g, e, s }

,那么它可以正确读出DataContext.Messages代替,并应工作。

<ListView ItemsSource="{Binding Path=Messages}" ... /> 

(这里所说的Path是可选的,因为如果你不指定属性的名称,然后结合假定它为Path属性的值)


作为一个方面说明,我没有看到你在表单的任何位置设置 DataContext,我也没有看到公共的 Messages属性。

MainWindow构造也许应该有一个行代码,看起来像这样的DataContext设置本身:

this.DataContext = this; 

而且你可能需要一个公共属性为您ObservableCollection<Message> messages所以ListView结合可以找到它:

public ObservableCollection<Message> Messages 
{ 
    get { return messages; } 
    set { messages = value; } 
} 

我不确定这些只是被忽视,或者如果你不知道你需要它们。

哦,如果你打算更改其中的任何约束性的和具有UI自动更新,你要实现INotifyPropertyChanged太:)

而且因为我在教程模式在这里,我想我也应该链接到这个答案:

Transitioning from Windows Forms to WPF

我会强烈建议通过它读取(和链接的文章)如果你是新来WPF是如何工作的,并从的WinForms到WPF的切换。这听起来像你:)

+0

所以真的,我还没有想法为什么它向我抱怨这件事。我“传递”给它的类型是'string',所以我不知道它为什么告诉我它是'char'。我认为这与BackgroundWorker有关。只有我认为这是因为相同的代码工作正常,没有BGWorker。当你遇到@Rachel错误时,你使用了BackgroundWorker吗? –

+2

@Aeron这些错误与后台工作无关,它们是通用的XAML绑定错误。当你编写'{Binding}'时,默认情况下'Source'被设置为'DataContext','Path'被设置为'Source'。当你编写ItemsSource =“{Binding Source = Messages}”时,你将该绑定的'Source'从当前的'DataContext'改为一个''Messages''的字符串,而一个字符串只不过是一个字符所以你将'ListView'绑定到'{M,e,s,s,a,g,e,s}'的字符数组,并且每个ListViewItem都有一个'DataContext'字符 – Rachel

+1

@Aeron查看我的回答更新:) – Rachel

4

不像许多.NET的错误,这些的意思是正是他们说什么......所有你需要做的就是阅读他们。使用这个当作一个范例:

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')

在XAML

某处,你正在试图将数据绑定一个名为SenderTextBlock.Text property属性......这些信息都在您的错误。但是,它继续说明数据绑定的对象是object类型,并且object类没有任何名为Sender的属性...因此...错误。

为了解决这个问题,找到TextBlockBinding,要么用你的类的实例确实有一个名为Sender属性,或者使用属性绑定到在定义交换objectobject类。

根据您所拥有的这些错误的数量来判断,我必须假设它们是由ItemTemplate中的Binding造成的,例如。您的集合中的每个项目都会导致相同的错误。

+2

“你的XAML中的某处”:-( Somewhere .... –

+0

加1 for“不像许多.NET错误...” – keuleJ

2

如果您使用ItemsSource属性,它假定您传递IEnumerable。默认情况下,如果WPF没有找到其他有用的东西,那么WPF也会将其作为类型的名称。由于字符串是IEnumerable(字符),因此列表项将绑定对象的类型名称传递给ItemTemplate,因为它是唯一可以解决的“合理”事情。而且,由于Char类型显然没有发件人和主题属性,因此您的代码将变为boom

作为证明,比较以下代码的输出和错误消息中的哈希码。

foreach (char c in "Message") { 
    Console.WriteLine(c.GetHashCode()); 
} 

而不是使用一个ListView的,只需要使用堆叠面板与它的数据源等于消息,并删除封闭控制:

<StackPanel DataSource={Binding Message} 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> 
+1

@Rachel的答案是一个更正确的解释。我错过了OP的绑定中的“源”,使其绑定到字符串“Message”。然而,我提出的解决方案仍然是正确的。 –