无法在 WPF C# 中正确绑定数据

本文关键字:绑定 数据 WPF | 更新日期: 2023-09-27 18:37:01

我是WPF和数据绑定的新手,经过数小时的狂欢和搜索Stackoverflow,我无法找到全面的解决方案。我正在尝试使用我的 KinectWindow.xaml 上使用数据绑定在 TextBlock 控件上显示文本:

 <TextBlock x:Name="InitText" 
            TextWrapping="Wrap" 
            Text="{Binding Source=ScanInitTextA, 
                           Path=ScanInitTextA, 
                           UpdateSourceTrigger=PropertyChanged}"

免费的 KinectWindow.xaml.cs 类具有以下属性:

string ScanInitText = "Preparing for Initial Scan.";    
 string ScanInitTextA
    { get { return (ScanInitText) ; }
        set { ScanInitTextA = value; }
    }

我已经进行了多次尝试,无论是直接从类绑定属性还是从 xaml 绑定属性。尝试执行任何操作时,我通常会收到此错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'ScanInitTextA' property not found on 'object' ''String' (HashCode=1828304777)'. 
BindingExpression:Path=ScanInitTextA; 
DataItem='String' (HashCode=1828304777); 
target element is 'TextBlock' (Name='InitText'); 
target property is 'Text' (type 'String')

据我了解,在对象字符串中找不到ScanInitTextA?

最后,我知道当我尝试从不同的类(不是 KinectWindow.xaml.cs,通过在 xaml 中引用该类并将绑定源更改为该类的名称)尝试类似的方法时,数据绑定确实有效,但由于其他原因,我更愿意通过此类执行此操作。

提前谢谢。 :)

无法在 WPF C# 中正确绑定数据

试试这个:

<TextBlock x:Name="InitText" 
                TextWrapping="Wrap" 
                Text="{Binding  Path=ScanInitTextA}"

错误消息指出您尝试在字符串对象本身上查找属性ScanInitTextA。我认为当前TextBlockSource之前已分配(可能为 DataContext)。

你试过吗

     <TextBlock x:Name="InitText" 
        TextWrapping="Wrap" 
        Text="{Binding  Path=ScanInitTextA, 
                       UpdateSourceTrigger=PropertyChanged}"

如果你把你的观点DataContext设置为自我,那么给Source是错误的。只需将绑定更新为:

 <TextBlock x:Name="InitText" 
        TextWrapping="Wrap" 
        Text="{Binding Path=ScanInitTextA, 
                       UpdateSourceTrigger=PropertyChanged}"/>

更新

需要的是一种绑定到主窗口属性的方法。这是执行该绑定的一种方法

<Window x:Name="KinectWindow"
        Title="My Kinect Show"
        ...>
    <TextBlock Text="{Binding ScanInitTextA, ElementName=KinectWindow}" />

请注意,如果您预计 ScanInitTextA 的值将被某些内容更改并且该更改需要自动显示,则仍需要使 ScanInitTextA 执行属性更改通知。请参阅下面的 #1 和 #2。

<小时 />

遵循 MVVM 类型系统并将 VM 放在窗口的数据上下文中的原始建议

  1. 首先,无论哪个类持有 ScanInitTextA,都需要实现 INotifyPropertyChanged 并使 ScanInitTextA 公开
  2. 其次,更好的绑定方法是将页面的数据上下文设置为具有 INotifyPropertyChanged 的类。这样做是因为它将所有数据集中在一个位置,并且页面的数据上下文由所有控件继承,因此此时页面的每个控件都只是绑定到属性名称。这是基本的 MVVM,其中 VM(视图模型)具有 INotifyPropertyChanged。

我们想在列表框中显示 Members ,字符串列表。最终,我们的绑定将只是{Binding Members}.

查看模型

public class MainVM : INotifyPropertyChanged 
{
 
    private List<string> _Members;
 
    public List<string> Members 
    { 
        get { return _Members; }
        set { _Members = value; OnPropertyChanged(); } 
    }
    public MainVM()
    {
        // Simulate Asychronous access, such as to a db.
 
        Task.Run(() =>
                    {
                        Members = new List<string>() {"Alpha", "Beta", "Gamma", "Omega"};
                        MemberCount = Members.Count;
                    });
    }
    /// <summary>Event raised when a property changes.</summary>
    public event PropertyChangedEventHandler PropertyChanged;
 
    /// <summary>Raises the PropertyChanged event.</summary>
    /// <param name="propertyName">The name of the property that has changed.</param>
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 
}
}

页面代码隐藏

   public partial class MainWindow : Window
    {
 
        public MainVM ViewModel { get; set; }
 
        public MainWindow()
        {
            InitializeComponent();
 
            // Set the windows data context so all controls can have it.
            DataContext = ViewModel = new MainVM();
 
        }
 
    }

具有绑定的页面 Xaml

   <ListBox Name="lbData"
                ItemsSource="{Binding Members}"
                SelectionMode="Multiple"
                Margin="10" />

这个例子取自我的博客文章:

Xaml:视图模型主页实例化和加载策略,便于绑定。