我有一个约束性问题,在过去的两天里我一直无法解决。我已经彻底地浏览了关于SO的大部分相关线程,但仍然无法确定错误所在。
我遇到的问题是程序中的一个文本框。其目的是显示用户从文件浏览器中选择的文件。我已经将它的text属性绑定到一个名为parameterFileSelected
的字符串,但文本框从未更新,即使调试似乎显示iNotifyPropertyChanged被正确调用和执行。
如果我的代码有错误,请帮我看看下面我的代码。
文本框是名为GenerateReports的xaml的一部分,该视图绑定到GenerateReportsViewModel,如下所示:
用于将datacontext设置为GenerateReportsViewModel的代码
<Grid >
<Grid.DataContext>
<vm:GenerateReportsViewModel/>
</Grid.DataContext>
<Grid.ColumnDefinitions>
....
TextBox的代码。我尝试过删除双向模式,将其更改为单向模式并删除该模式,但没有区别。
<TextBox Grid.Column="2" Grid.Row="1" Margin="5" Text="{Binding parameterFileSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" ></TextBox>
要获取文件浏览器,然后将选定的文件结果传递给GenerateReportsViewModel,这是codebehind文件中的函数。genviewmodel在codebehind文件的开头初始化为GenerateReportsViewModel genviewmodel=new GenerateReportsViewModel()
private void ParaFileButtonClick(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
DataContext = genViewModel;
genViewModel.updateParameterFileSelected(openFileDialog.FileName.ToString());
}
}
这是在GenerateReportsViewModel中调用的代码,用于更新文本框绑定到的参数File选择字符串。
class GenerateReportsViewModel : ViewModelBase
{
private string _parameterFileSelected;
public string parameterFileSelected
{
get { return _parameterFileSelected; }
set { SetValue(ref _parameterFileSelected, value); }
}
public void updateParameterFileSelected(string parameterFile)
{
parameterFileSelected = parameterFile;
}
}
以下是viewmodel附加到的ViewModelBase。
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void SetValue<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
if (property != null)
{
if (property.Equals(value)) return;
}
OnPropertyChanged(propertyName);
property = value;
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
应用Kevin的建议后编辑工作html" target="_blank">解决方案
为了简单起见,Datacontext是在XAML中设置的。
<Grid>
<Grid.DataContext>
<vm:GenerateReportsViewModel x:Name="generateReportsViewModel"/>
</Grid.DataContext>
然后,我直接从后面的代码中调用文本框绑定到的字符串。
private void ParaFileButtonClick(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == true)
{
generateReportsViewModel.parameterFileSelected = openFileDialog.FileName.ToString();
}
}
ViewModel现在使用Kevin的ViewModelBase:
public class GenerateReportsViewModel : ViewModelBase
{
public string parameterFileSelected
{
get { return this.GetValue<string>(); }
set { this.SetValue(value); }
}
}
谢谢凯文的解决方案,现在我2天的问题解决了。
我发现我以前的ViewModelBase调用的是iNotifyPropertyChanged,但不知怎的,当视图更新时,该值改为null。
我试图理解为什么在viewModel中使用ref关键字。我从Classon和Baxter的书中学到了创建BaseViewModel的好方法,你可以在下面找到。视图模型实现了INotifyPropertyChanged,就像您所做的那样。你对[CallerMemberName]所做的很好,这真的很神奇,因为它我们可以引用我们的属性。
视图模型使用字典中的索引来存储其属性。它使用了一个非常巧妙的技巧,通过单词键查看是否包含属性的字符串名称。否则,我们将返回默认的T值。
public class CommonBaseViewModel: INotifyPropertyChanged
{
private Dictionary<string, object> Values { get; set; }
protected CommonBaseViewModel()
{
this.Values = new Dictionary<string, object>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected T GetValue<T>([CallerMemberName] string name=null)
{
if (this.Values.ContainsKey(name))
{
return (T)this.Values[name];
}
else
{
return default(T);
}
}
protected void SetValue(object value, [CallerMemberName] string name = null)
{
this.Values[name] = value;
//notify my property
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected void OnPropertyChanged([CallerMemberName] string name=null)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if(this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
}
至于GenerateReportViewModel,使用我提供给您的公共视图模型,您的类将变成:
public class GenerateReportsViewModel : CommonViewModelBase
{
private string _parameterFileSelected;
public string parameterFileSelected
{
get { return _parameterFileSelected; }
set { SetValue(ref _parameterFileSelected, value); }
}
get
{
return this.GetValue<string>();
}
set
{
this.SetValue(value);
}
public void updateParameterFileSelected(string parameterFile)
{
parameterFileSelected = parameterFile;
}
}
哦,在我忘记之前,我不知道这是否是你的意图,但你的GenerateReportViewModel是私有的。这会对代码产生一些影响。别忘了,德法特的课程是私人的!
至于后面的代码,尽管这可能被认为是不好的做法,但我建议您在初始化页面时构建一个私有字段(OpenFileDialog_openFileDialog)。因为每次单击按钮时都会消耗更多的数据。
//编辑我已经检查了我的代码,似乎该属性没有正确编程。公共类GenerateReportsViewModel:CommonViewModelBase{
private string _parameterFileSelected;
public string parameterFileSelected
{
get
{
return this.GetValue<string>();
}
set
{
this.SetValue(value);
}
public void updateParameterFileSelected(string parameterFile)
{
parameterFileSelected = parameterFile;
}
}
更多关于构建页面和绑定视图模型的评论。在创建页面时,必须为该页面创建视图模型,然后将其绑定到数据上下文。我不知道您在代码中做了什么,但我可以提供以下示例:
public GenerateReportView()
{
InitializeComponent();
//Some operations
var generateReportViewModel = new GenerateReportViewModel();
this.DataContext = generateReportViewModel;
}
最后是我的XAML代码 我已经尝试将绑定模式设置为twoway和其他绑定设置,但行为没有任何变化。我想做的是弄清楚如何让drop功能像手动键入框并离开框一样工作,而不必绕过绑定并直接设置属性。
本文向大家介绍wpf 实现INotifyPropertyChanged,包括了wpf 实现INotifyPropertyChanged的使用技巧和注意事项,需要的朋友参考一下 示例 INotifyPropertyChanged是绑定源(即DataContext)使用的接口,以使用户界面或其他组件知道属性已更改。WPF在看到PropertyChanged事件引发时会自动为您更新UI 。最好在所有视图
我是C#新手,我不断收到以下无法删除的错误。 我的代码如下,我不能确切地说出哪一行导致了错误,但我怀疑它与RibbonRadioButtons有关,因为如果我删除它们,我不会得到错误。只有在单击两个或更多单选按钮后,错误才会出现。ComboBoxItem上的一个回答继续抛出绑定错误,尽管style暗示是多个Refresh()语句导致了这个问题,但我不知道如何避免这个问题。 有人能帮我解决这个问题吗
问题内容: 我有一个绑定到我的EventTracker bean的JTable,本质上是一个列表的包装,我将仅将其用作附加/清除(即,简单的日志)。问题是,当我将条目添加到列表中并尝试触发事件时,我看不到任何更改。我正在使用NetBeans IDE。 EventTracker bean被添加到视图中并实例化为eventTracker1。从那里,我右键单击表格,然后选择“表格内容…”。表模型已绑定到
我已经审阅了Microsoft提供的关于触发器的文档。[https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-trigger?tabs=python][1] 事实上,在Azure函数中使用参数允许我们检索blob和一些属性(),我们还可以使用函数读取字节,但是我们如何将字节转换为
使用Datagridtemplatecolumn将WPFDatagrid绑定到组合框。很难获得组合框绑定的selectedItem。我发现了类似的例子,但这并不能解决我的问题。 请在下面找到我的 XAML 的代码片段和数据结构: 我在上面定义了一个数据结构,它实现了INotifyPropertychanged接口。 现在,在视图模型中,有一个可观察的X列表集合,即XList,它绑定到XAML中的数