C# 在WPF/MVVM应用程序中设置编辑状态
在WPF应用程序中使用MVVM模式,我希望处理记录的“编辑状态”。 每次用户开始编辑记录时,该窗口都应切换到“编辑”模式,在代码中很容易用名为IsEditing的布尔属性表示。 这允许激活/停用UI按钮等 我知道这样的属性应该包含在ViewModel中。 但是,如何确保一旦用户开始编辑其中一个字段,IsEditing就设置为true? 我发现的唯一方法是将IsEditing显式分配到模型字段的包装器中。 有没有更好、更聪明的方法来做到这一点,也许是以集中的方式?我在我的方法中看到的缺点是,对于一个领域来说,冗长和可能忘记这样做。 也许有一种完全不同的方法从一开始就处理这样的问题 但是,我的模型实体框架核心应该是不相关的:C# 在WPF/MVVM应用程序中设置编辑状态,c#,wpf,mvvm,C#,Wpf,Mvvm,在WPF应用程序中使用MVVM模式,我希望处理记录的“编辑状态”。 每次用户开始编辑记录时,该窗口都应切换到“编辑”模式,在代码中很容易用名为IsEditing的布尔属性表示。 这允许激活/停用UI按钮等 我知道这样的属性应该包含在ViewModel中。 但是,如何确保一旦用户开始编辑其中一个字段,IsEditing就设置为true? 我发现的唯一方法是将IsEditing显式分配到模型字段的包装器中。 有没有更好、更聪明的方法来做到这一点,也许是以集中的方式?我在我的方法中看到的缺点是,对于一
public class City
{
public string Id { get; set; }
public string Name { get; set; }
}
关联的ViewModel I仅包含相关代码:
public class CityVM : INotifyPropertyChanged
{
private bool _isEditing;
public bool IsEditing
{
get { return _isEditing; }
set
{
if (value!=_isEditing)
{
_isEditing = value;
NotifyPropertyChanged();
}
}
}
public string Name
{
get { return _model.Name; }
set
{
if (value!=_model.Name)
{
_model.Name = value;
NotifyPropertyChanged();
IsEditing = true;
}
}
}
}
我理解你的问题,并且已经有了同样的问题。我的解决方案是基于触发器触发commmands for GotFocus和LostFocus更新布尔值,我知道这不是最好的选择,但这是我唯一的选择 我会准备一个剪报并更新我的回复 编辑:我找到了更好的方法 创建一个行为并将其附加到文本框,是一个更干净的解决方案。我的第一个建议是,它不会让你的代码变脏
public static class EditingStateBehavior
{
#region IsEditing
public static bool GetIsEditing(DependencyObject obj) => (bool)obj.GetValue(IsEditingProperty);
public static void SetIsEditing(DependencyObject obj, bool value) => obj.SetValue(IsEditingProperty, value);
public static readonly DependencyProperty IsEditingProperty =
DependencyProperty.Register(
"IsEditing",
typeof(bool),
typeof(EditingStateBehavior));
#endregion IsEditing
#region Enabling
public static bool GetIsEditingEnabled(DependencyObject obj) => (bool)obj.GetValue(IsEditingEnabledProperty);
public static void SetIsEditingEnabled(DependencyObject obj, bool value) => obj.SetValue(IsEditingEnabledProperty, value);
public static readonly DependencyProperty IsEditingEnabledProperty =
DependencyProperty.Register(
"IsEditingEnabled",
typeof(bool),
typeof(TextBox),
new PropertyMetadata(OnIsEditingEnabledChanged));
private static void OnIsEditingEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox is null) return;
textBox.GotFocus += (x, p) => UpdateStatus(x as FrameworkElement, true);
textBox.LostFocus += (x, p) => UpdateStatus(x as FrameworkElement, false);
//Also, you cam implement something to handle if you don't want to receive notifications anymore....
}
private static void UpdateStatus(FrameworkElement frameworkElement, bool value) => frameworkElement.SetValue(IsEditingProperty, value);
#endregion Enabling
}
在您的文本框中:
<TextBox
Grid.Row="1"
Margin="3" Grid.ColumnSpan="1"
VerticalContentAlignment="Center"
local:EditingStateBehavior.IsEditing="{Binding IsEditing, Mode=TwoWay}"
local:EditingStateBehavior.IsEditingEnabled="True"
Text="{Binding SomeText}" />
不要忘记设置模式:双向
“IsEditingEnabled”必须存在,因为需要获取文本框引用来钩住事件,因此当窗口加载时,将触发“OnIsEditingEnabledChanged”,为您提供正确的监控控制。当然,如果您想要实现一个控件来停止以监视编辑状态或更改事件,您将在那里进行更改
我做了一个小项目来测试它,自由地看了看
无论如何,你的虚拟机是没有意义的。避免堆栈溢出的唯一方法是检查IsEditing是否不同,因为您在setter中用true覆盖了用户的值。您完全正确,直接在stackoverflow上编辑代码是一个错误。IsEditing由任何其他属性设置,但显然不是由其自身设置的。我现在已经改正了。