gpt4 book ai didi

c# - PropertyChangedEventHandler 两次都为空,但绑定(bind)只工作一次,为什么?

转载 作者:行者123 更新时间:2023-12-03 10:46:26 26 4
gpt4 key购买 nike

我做了一个小项目来学习一点关于 MVVM 的知识。这是一个计算器,可以计算您何时可以下类回家。

我做了一个UserControl有两个文本框和一个标签作为简单的“时间选择器”。这个 Usercontrol 有一个 ViewModel(主窗口甚至有一个),它管理一个 Timepicker 的时间。它具有三个属性:一个名为 TimeValue 的 int这只是小时和分钟的值以及两个称为 Hours 的整数和 Minutes .我的两个文本框绑定(bind)到它们并显示它们。通过文本框设置一个值也会重置时间,设置时间(通过属性)重置小时和分钟,设置此值后两个文本框都会更新。

这很好用。现在我想添加第二个属性,名为 ReadOnly .显示时间的 TimePicker 需要 ReadOnly。手动设置这个时间是没有意义的,所以我希望有可能设置两个文本框 IsReadOnly属性(property)。
ReadOnly现在是 UserControl 的第二个属性。因为我很懒,我想通过 UserControl 直接绑定(bind)属性和两个文本框,并且只绑定(bind) IsReadOnly -UserControl 的属性。

这是我的想法代码(用户控件):

public partial class TimeBox : UserControl, INotifyPropertyChanged
{
private SingleTimeViewModel viewModel;

//... other Properties

public static DependencyProperty ReadOnlyProperty = DependencyProperty.Register("ReadOnly", typeof(Boolean), typeof(TimeBox), new PropertyMetadata(false));

// Schnittstellen-Ereignis
public event PropertyChangedEventHandler PropertyChanged;
protected internal void OnPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}

public TimeBox()
{
InitializeComponent();
viewModel = new SingleTimeViewModel(SingleTime.CreateSingleTime());
this.DataContext = viewModel;
}

//... Code of other Properties

private bool _ReadOnly;
public bool ReadOnly
{
get
{
return _ReadOnly;
}
set
{
if (_ReadOnly == value)
return;
_ReadOnly = value;
OnPropertyChanged("ReadOnly");
}
}

//... Other Methods
}

这通过 XAML 绑定(bind)到两个文本框( Text 的绑定(bind)导致 ViewModel,IsReadOnly 应该绑定(bind)到 TimeBox):
<UserControl x:Name="TimeBoxControl" x:Class="TimeCalculator.TimeBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
... >
<WrapPanel Grid.Column="7" HorizontalAlignment="Stretch" Margin="0,0,0,0" Grid.Row="1" VerticalAlignment="Center" >
<TextBox x:Name="txtBxHours" ... Text="{Binding Hours}" ... IsReadOnly="{Binding ReadOnly, ElementName=TimeBoxControl}" />
<Label x:Name="lblSeparator" ... />
<TextBox x:Name="txtBxMinutes" ... Text="{Binding Minutes}" ... IsReadOnly="{Binding ReadOnly, ElementName=TimeBoxControl}" />
</WrapPanel>
</UserControl>

InitializeComponent 之后,我在项目主窗口的构造函数中将值设为只读。 .因此我使用了以下几行:
this.TmBxMayGo.ReadOnly = true;
this.TmBxMustGo.ReadOnly = true;
this.TmBxTimeUntilMayGo.ReadOnly = true;
this.TmBxTimeUntilMustGo.ReadOnly = true;
this.TmBxCurrentOvertime.ReadOnly = true;

这不起作用,经过一些调试我发现它不起作用,因为 PropertyChangedEventHandler PropertyChanged一直是 null .
我进行了很多搜索以找到解决此问题的方法,但我没有犯任何常见错误(例如忘记 : INotifyPropertyChanged ,字符串中的错误名称或其他)。

我终于放弃了,通过 ViewModel 做到了。但后来我意识到 PropertyChangedEventHandler PropertyChanged也是 null当我通过 ViewModel 设置它时,但调用后文本框是只读的。

现在我有两个问题:
  • 为单个用户控件创建自己的 ViewModel 有意义吗?
  • 为什么呢?怎么可能PropertyChangednull两次但只工作一次?
  • 最佳答案

  • 是的,为单个独立的逻辑分离 UI 使用单个 ViewModel 是有意义的。它将责任与主视图模型分开。所以把你所有的属性放在你的 ViewModel 中。
  • WPF 仅将处理程序附加到 INotifyPropertyChanged 对象的 PropertyChanged 事件,当该对象设置为 View 的 DataContext 时,这就是在设置用户控件的 DataContext 之前 PropertyChanged 为空的原因。并且您的文本框仍然被禁用,因为在初始化绑定(bind)时,这些属性的 getter 会被调用,并且 UI 会使用您提供的默认值进行更新。
  • 关于c# - PropertyChangedEventHandler 两次都为空,但绑定(bind)只工作一次,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24367619/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com