C# 绑定 DataContext 和 INotifyPropertyChanged
C# Binding with DataContext and INotifyPropertyChanged
我做错了什么?
我有一个 Class Model.cs 有我的 DataContext
我旁边有一个 Button 和一个 TextBlock。我已尝试绑定和实施 INotifyPropertyChanged。
单击该按钮时,它会调用一个使用 WinForms 查找文件夹位置并将其显示在 TextBlock
中的方法
但它没有更新。如果我调试,我会正确获取路径。
非常感谢任何帮助。
MainWindow.xaml
<Button Name="projectLocationBtn"
Width="150"
Height="30"
Click="projectLocationBtn_Click">
<StackPanel Orientation="Horizontal">
<fa:FontAwesome Icon="FolderOpen" Margin="0 0 10 0" />
<TextBlock Text="Select Location" />
</StackPanel>
</Button>
<StackPanel Orientation="Horizontal" Margin="20 0 0 0">
<fa:FontAwesome Icon="AngleRight" Margin="0 0 10 0"/>
<TextBlock Width="800"
TextAlignment="Left"
TextWrapping="NoWrap"
Text="{Binding ProjectLocation}"/>
</StackPanel>
MainWindow.xaml.cs
using M = MercuryTemplateGenerator.Model;
public MainWindow()
{
InitializeComponent();
DataContext = new M.Model();
}
private void projectLocationBtn_Click(object sender, RoutedEventArgs e)
{
M.Model m = new M.Model();
m.GetLocation();
}
型号Class
using Winforms = System.Windows.Forms;
namespace MercuryTemplateGenerator.Model
{
public class Model: INotifyPropertyChanged
{
string _projectLocation;
string _projectName;
public Model() {}
public string ProjectName
{
get {
return _projectName; }
set {
_projectName = value;
OnPropertyChanged("ProjectName");
}
}
public string ProjectLocation
{
get {
return _projectLocation; }
set {
_projectLocation = value;
OnPropertyChanged("ProjectLocation");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(property));
}
public void GetLocation()
{
// get path to desktop
var startPath =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Winforms.FolderBrowserDialog folderDialog = new
Winforms.FolderBrowserDialog();
folderDialog.ShowNewFolderButton = false;
folderDialog.SelectedPath = startPath;
Winforms.DialogResult pathResult = folderDialog.ShowDialog();
if (pathResult == Winforms.DialogResult.OK)
{
_projectLocation = folderDialog.SelectedPath;
}
}
}
}
非常感谢。
在 GetLocation 函数中,您需要设置 ProjectLocation 属性 以引发 PropertyChanged 事件,如果您直接设置 _projectLocation 私有字段,则不会引发该事件,因为它在 setter 的 属性
错误是您有一个模型实例用于页面的 dataContext 并且有另一个您在内部调用的实例 projectLocationBtn_Click。如果视图绑定到 dataContext,则意味着它是 class 的特殊实例位于视图下,视图将从那里获取新数据。您需要在同一模型实例上调用 GetLocation 方法。例如,您可以将您的第一个模型保存到字段中。
_dataContext = new M.Model();
DataContext = _dataContext;
然后在处理程序中使用这个实例
private void projectLocationBtn_Click(object sender, RoutedEventArgs e)
{
_dataContext.GetLocation();
}
- 我看出来了,毕竟你没有调用OnPropertyChanged("ProjectLocation"),所以不行。
要调用它,您必须调用 ProjectLocation 属性
的 setter
替换:
_projectLocation = folderDialog.SelectedPath;
与
ProjectLocation = folderDialog.SelectedPath;
- 关于您的信息:检查 Button 的点击如何通过 XAML 文件中的绑定工作绑定到 DataContext。
https://www.codeproject.com/Articles/238657/How-to-use-Commands-in-WPF
我做错了什么?
我有一个 Class Model.cs 有我的 DataContext
我旁边有一个 Button 和一个 TextBlock。我已尝试绑定和实施 INotifyPropertyChanged。
单击该按钮时,它会调用一个使用 WinForms 查找文件夹位置并将其显示在 TextBlock
中的方法但它没有更新。如果我调试,我会正确获取路径。
非常感谢任何帮助。
MainWindow.xaml
<Button Name="projectLocationBtn"
Width="150"
Height="30"
Click="projectLocationBtn_Click">
<StackPanel Orientation="Horizontal">
<fa:FontAwesome Icon="FolderOpen" Margin="0 0 10 0" />
<TextBlock Text="Select Location" />
</StackPanel>
</Button>
<StackPanel Orientation="Horizontal" Margin="20 0 0 0">
<fa:FontAwesome Icon="AngleRight" Margin="0 0 10 0"/>
<TextBlock Width="800"
TextAlignment="Left"
TextWrapping="NoWrap"
Text="{Binding ProjectLocation}"/>
</StackPanel>
MainWindow.xaml.cs
using M = MercuryTemplateGenerator.Model;
public MainWindow()
{
InitializeComponent();
DataContext = new M.Model();
}
private void projectLocationBtn_Click(object sender, RoutedEventArgs e)
{
M.Model m = new M.Model();
m.GetLocation();
}
型号Class
using Winforms = System.Windows.Forms;
namespace MercuryTemplateGenerator.Model
{
public class Model: INotifyPropertyChanged
{
string _projectLocation;
string _projectName;
public Model() {}
public string ProjectName
{
get {
return _projectName; }
set {
_projectName = value;
OnPropertyChanged("ProjectName");
}
}
public string ProjectLocation
{
get {
return _projectLocation; }
set {
_projectLocation = value;
OnPropertyChanged("ProjectLocation");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(property));
}
public void GetLocation()
{
// get path to desktop
var startPath =
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Winforms.FolderBrowserDialog folderDialog = new
Winforms.FolderBrowserDialog();
folderDialog.ShowNewFolderButton = false;
folderDialog.SelectedPath = startPath;
Winforms.DialogResult pathResult = folderDialog.ShowDialog();
if (pathResult == Winforms.DialogResult.OK)
{
_projectLocation = folderDialog.SelectedPath;
}
}
}
}
非常感谢。
在 GetLocation 函数中,您需要设置 ProjectLocation 属性 以引发 PropertyChanged 事件,如果您直接设置 _projectLocation 私有字段,则不会引发该事件,因为它在 setter 的 属性
错误是您有一个模型实例用于页面的 dataContext 并且有另一个您在内部调用的实例 projectLocationBtn_Click。如果视图绑定到 dataContext,则意味着它是 class 的特殊实例位于视图下,视图将从那里获取新数据。您需要在同一模型实例上调用 GetLocation 方法。例如,您可以将您的第一个模型保存到字段中。
_dataContext = new M.Model(); DataContext = _dataContext;
然后在处理程序中使用这个实例
private void projectLocationBtn_Click(object sender, RoutedEventArgs e)
{
_dataContext.GetLocation();
}
- 我看出来了,毕竟你没有调用OnPropertyChanged("ProjectLocation"),所以不行。 要调用它,您必须调用 ProjectLocation 属性 的 setter
替换:
_projectLocation = folderDialog.SelectedPath;
与
ProjectLocation = folderDialog.SelectedPath;
- 关于您的信息:检查 Button 的点击如何通过 XAML 文件中的绑定工作绑定到 DataContext。 https://www.codeproject.com/Articles/238657/How-to-use-Commands-in-WPF