c# - 在 'object' 上找不到 WPF/XAML 属性

标签 c# .net wpf xaml

我在一个新的 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')

  1. 目标属性是“文本”(类型“字符串”)
  2. 目标元素是 'TextBlock' (Name='');
  3. BindingExpression:Path=Sender;
  4. DataItem='Char' (哈希码=6619237);
  5. 在“对象”“Char”(HashCode=6619237) 上未找到“Sender”属性。
  6. BindingExpression路径错误:
  7. 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)错误

7 我有 no idea what it means

因为我看到你的 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 :)

因为我在这里处于教程模式,所以我想我也应该链接到这个答案:

Transitioning from Windows Forms to WPF

如果您不了解 WPF 的工作原理并且要从 Winforms 切换到 WPF,我强烈建议通读它(以及链接的文章)。听起来像你:)

关于c# - 在 'object' 上找不到 WPF/XAML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24558379/

相关文章:

c# - WPF 中工具提示或弹出窗口上的可单击超链接

c# - 更改 toolStripLabel C#.Net 的颜色

WPF MaskedTextBox 值绑定(bind)(无掩码绑定(bind))

wpf - 首次使用 WPF 中的 WCF 非常慢

c# - DepencyProperty 未通过 UserControl 上的绑定(bind)进行更新

c# - 左加入两个列表并使用 Linq 从右边维护一个属性

c# - 将多个文本属性写入一个 txt 文件

c# - 重复类型错误?

.net - 命名:价格表或。价目单价目表

wpf - 当 WPF ProgressBar 达到 100% 时,如何停止它的脉冲/动画?