2016-01-19 60 views
1

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

const string EXAMPLE = "Example"; 

string example; 

public string Example 
{ 
    get { return example; } 
    set 
    { 
     if (value == example) return; 
     example = value; 
     OnPropertyChanged(EXAMPLE); 
    } 
} 

这些属性在我的视图中,以便使用该控件的用户可以轻松设置它们。在我的ViewModel中,我有一个相同的属性,我需要将这些属性绑定在一起,以便它们和它们的后备字段始终具有相同的值。我讨厌代码重复。

说实话,整个方法感觉不对,通常这是一个很好的迹象表明,我正在从错误的方向接近整个事物或误解根本的东西。

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

+0

这个帖子最初读“定制”的控制,我事实上是在试图创建用户控件 –

回答

2

我想确定的第一件事是,你真的想做一个CustomControl而不是一个UserControl。我相信question基本上和你的一样,只是措词不同而已。

UserControl比自​​定义控件更适合MVVM模式,因为您将有.xaml(和.xaml.cs)文件以及.cs文件作为ViewModel。另一方面,CustomControl永远不会用MVVM完成,因为视觉外观(视图)是通过ControlTemplate定义和覆盖的。

既然你说过你有View和ViewModel,那么让我们考虑一下你将如何用你的文本框实现你想要的行为。您的文本框必须验证并拒绝超出您所需值范围的用户输入。这意味着您的View代码隐藏必须具有属性和逻辑,以控制View中定义的文本框输入值的限制。你已经在这里违反了MVVM。

当你说你有一个视图,这让我觉得你正在编写一个UserControl。但是您的需求(文本框的自定义行为)表明您确实需要一个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> 
+0

是的,我的意思是一个用户控件,而不是自定义控件。抱歉。 –

2

自定义控件中没有MVVM。

任何控件只在视图图层中。所以你需要做的是将相关的DP公开给你不知道的消费者。

在自定义控件中,您需要定义您的控件行为,它如何响应更改DP值以及消费者可以使用的内容。在默认模板中,您可以定义如何显示此控件。

消费者可能想要设置或获取一些dp值,因此他必须将自定义Control'dp绑定到ViewModel中的属性,但这取决于他。

相关问题