无法在 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 中引用该类并将绑定源更改为该类的名称)尝试类似的方法时,数据绑定确实有效,但由于其他原因,我更愿意通过此类执行此操作。
提前谢谢。 :)
试试这个:
<TextBlock x:Name="InitText"
TextWrapping="Wrap"
Text="{Binding Path=ScanInitTextA}"
错误消息指出您尝试在字符串对象本身上查找属性ScanInitTextA
。我认为当前TextBlock
的Source
之前已分配(可能为 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 放在窗口的数据上下文中的原始建议
- 首先,无论哪个类持有 ScanInitTextA,都需要实现 INotifyPropertyChanged 并使 ScanInitTextA 公开。
- 其次,更好的绑定方法是将页面的数据上下文设置为具有 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:视图模型主页实例化和加载策略,便于绑定。