如何使用UserControl DP和MVVM

时间:2016-08-27 11:09:38

标签: wpf xaml mvvm user-controls

我在互联网上找不到这个问题的答案。

有没有办法在UserControl DP和MVVM中一起使用?

例如,我创建了UserControl,我需要在其上显示一些文本。我的UserControl有DP,它从消费者那里获取一些数据(f.e. string)。

我背后有一些代码:

<input type="button" id="the-button" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

以下是ViewModel类的代码:

public partial class MyUserControl : UserControl
{

    public MyUserControl()
    {
        InitializeComponent();
    }

    ***

    public string Text
    {
        get { return (PointCollection)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(nameof(Text),
            typeof(string),
            typeof(MyUserControl),
            new FrameworkPropertyMetadata(null, new PropertyChangedCallback(TextChanged))
            );

    private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
         ((MyUserControl)d).DataContext.Txt = (string)e.NewValue;
    }

    ***

}

这里有一些UserControl的XAML代码,我希望将TextBlock的文本绑定到ViewModel的属性Txt,所以:

class MyUserControlViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string _txt;

    public MyUserControlViewModel(){}

    ***

    public string Txt
    {
        get{return _txt;}
        set
        {
            if(_txt!= value)
            {
                _txt= value;
                OnPropertyChanged("Txt");
            }
        }
    }

    ***

}

所以,如果我这样做的话,当我在消费者应用程序的DP Text中放入一些数据时,我看不到DP文本的任何变化和Txt的任何变化。

我该怎么办?

1 个答案:

答案 0 :(得分:0)

您没有提到为什么要同时使用依赖项属性和视图模型,但是很容易让它工作。您只需要使用要使用的视图模型而不是其他视图模型。这是错误的viewmodel:

<UserControl.DataContext>
    <local:SimpleWPFChartExample />
</UserControl.DataContext>

这是正确的:

<UserControl.DataContext>
    <local:MyUserControlViewModel />
</UserControl.DataContext>

至少,基于你的问题似乎就是这种情况。但是你有很多复制和粘贴错误:例如,你的Text字符串属性getter会将返回值从GetValue()转换为PointCollection;那甚至不会编译。这也不会:((MyUserControl)d).DataContext.Txt = (string)e.NewValue;

这将编译:

private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var ctl = ((MyUserControl)d);
    var vm = (MyUserControlViewModel)ctl.DataContext;
    vm.Txt = (String)e.NewValue;
}

因此,据我所知,您确实在实际代码中使用了正确的viewmodel,在这种情况下,问题出现在您未在此处共享的代码中。可能问题在于您设置Text时所做的一切。

如果你能提供一个完整的,最小的,单个属性的例子来编译,那将会很有帮助,但是在运行时失败以满足你的期望。