C# 视图中的属性必须与ViewModel中的相同属性匹配

C# 视图中的属性必须与ViewModel中的相同属性匹配,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在创建一个用户控件(一个只接受整数的文本框)。控件必须具有属性以指定最大/最小值以及是否允许负值等)。我正在使用MVVM,在我看来,我拥有公共属性,例如 const string EXAMPLE = "Example"; string example; public string Example { get { return example; } set { if (value == example) return; example

我正在创建一个用户控件(一个只接受整数的文本框)。控件必须具有属性以指定最大/最小值以及是否允许负值等)。我正在使用MVVM,在我看来,我拥有公共属性,例如

const string EXAMPLE = "Example";

string example;

public string Example
{
    get { return example; }
    set
    {
        if (value == example) return;
        example = value;
        OnPropertyChanged(EXAMPLE);
    }
}
在我看来,这些属性是可以让使用控件的人轻松设置的。在我的ViewModel中,我有一个相同的属性,我需要将这些属性绑定在一起,以便它们和它们的支持字段始终具有相同的值。我也讨厌代码重复

老实说,整个方法感觉是错误的,通常这是一个很好的迹象,表明我从错误的方向来处理整个事情,或者误解了一些基本的东西


我以前使用过WPF,但这是第一次尝试使用自定义控件

自定义控件中没有MVVM

任何控件都仅在视图层中。因此,您需要做的是向您不了解的消费者公开相关DP

在自定义控件中,您需要定义控件行为,它如何对DP值的更改作出反应,以及使用者应该可以使用什么。在默认模板中,定义要如何显示此控件


使用者可能希望设置或获取一些dp值,因此他必须将自定义控件的dp绑定到其ViewModel中的属性,但这取决于他。

自定义控件中没有MVVM

任何控件都仅在视图层中。因此,您需要做的是向您不了解的消费者公开相关DP

在自定义控件中,您需要定义控件行为,它如何对DP值的更改作出反应,以及使用者应该可以使用什么。在默认模板中,定义要如何显示此控件


使用者可能希望设置或获取一些dp值,因此他必须将自定义控件的dp绑定到其ViewModel中的属性,但这取决于他。

我要确保的第一件事是,您确实在尝试创建自定义控件,而不是用户控件。我相信这与你的基本相同,只是措辞不同

UserControl比CustomControl更容易使用MVVM模式,因为您将有一个.xaml(和.xaml.cs)文件和一个.cs文件作为ViewModel。另一方面,由于视觉外观(视图)是通过ControlTemplate定义和覆盖的,因此,MVVM永远不会完成CustomControl

既然您说您有一个视图和视图模型,那么让我们来考虑一下如何使用文本框实现您想要的行为。您的文本框必须验证并拒绝超出所需值范围的用户输入。这意味着您的视图代码必须具有控制视图中定义的文本框输入值中的限制的属性和逻辑。您已经在此处违反了MVVM

当你说你有一个视图时,我觉得你在写一个用户控件。但是您的需求(textbox的自定义行为)表明您确实需要一个CustomControl,而不使用MVVM

如果您同意需要CustomControl,下面是一个简单的示例:

 public class RestrictedTextBox : TextBox
 {
    public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(int), typeof(RestrictedTextBox), new PropertyMetadata(int.MaxValue));

    public RestrictedTextBox()
    {
        PreviewTextInput += RestrictedTextBox_PreviewTextInput;
    }

    public int MaxValue
    {
        get
        {
            return (int)GetValue(MaxValueProperty);
        }
        set
        {
            SetValue(MaxValueProperty, value);
        }
    }


    private void RestrictedTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        int inputDigits;
        RestrictedTextBox box = sender as RestrictedTextBox;
        if (box != null)
        {

            if (!e.Text.All(Char.IsDigit))
            {
                // Stops the text from being handled
                e.Handled = true;
            }
            else if (int.TryParse(box.Text + e.Text, out inputDigits))
            {
                if (inputDigits > MaxValue)
                    e.Handled = true;
            }
        }
    }
}
XAML用法:

    <local:RestrictedTextBox MaxValue="100"></local:RestrictedTextBox>

我要确保的第一件事是,您确实在尝试创建CustomControl,而不是UserControl。我相信这与你的基本相同,只是措辞不同

UserControl比CustomControl更容易使用MVVM模式,因为您将有一个.xaml(和.xaml.cs)文件和一个.cs文件作为ViewModel。另一方面,由于视觉外观(视图)是通过ControlTemplate定义和覆盖的,因此,MVVM永远不会完成CustomControl

既然您说您有一个视图和视图模型,那么让我们来考虑一下如何使用文本框实现您想要的行为。您的文本框必须验证并拒绝超出所需值范围的用户输入。这意味着您的视图代码必须具有控制视图中定义的文本框输入值中的限制的属性和逻辑。您已经在此处违反了MVVM

当你说你有一个视图时,我觉得你在写一个用户控件。但是您的需求(textbox的自定义行为)表明您确实需要一个CustomControl,而不使用MVVM

如果您同意需要CustomControl,下面是一个简单的示例:

 public class RestrictedTextBox : TextBox
 {
    public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(int), typeof(RestrictedTextBox), new PropertyMetadata(int.MaxValue));

    public RestrictedTextBox()
    {
        PreviewTextInput += RestrictedTextBox_PreviewTextInput;
    }

    public int MaxValue
    {
        get
        {
            return (int)GetValue(MaxValueProperty);
        }
        set
        {
            SetValue(MaxValueProperty, value);
        }
    }


    private void RestrictedTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        int inputDigits;
        RestrictedTextBox box = sender as RestrictedTextBox;
        if (box != null)
        {

            if (!e.Text.All(Char.IsDigit))
            {
                // Stops the text from being handled
                e.Handled = true;
            }
            else if (int.TryParse(box.Text + e.Text, out inputDigits))
            {
                if (inputDigits > MaxValue)
                    e.Handled = true;
            }
        }
    }
}
XAML用法:

    <local:RestrictedTextBox MaxValue="100"></local:RestrictedTextBox>


是的,我指的是用户控件,而不是自定义控件。对不起,是的,我指的是用户控件,不是自定义控件。对不起,这篇文章最初读的是“自定义”控件,我实际上是在尝试创建一个用户控件。这篇文章最初读的是“自定义”控件,我实际上是在尝试创建一个用户控件