脱发和MVVM用户控件 [英] Hair loss and MVVM user controls

查看:144
本文介绍了脱发和MVVM用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#编写和放大器的用户控件; WPF使用MVVM模式。



所有我想要做的是有暴露在控制之外的绑定视图模型的属性。我希望能够绑定到它,我想该财产的任何更改通过绑定到暴露值控制之外的任何事情有所回升。



这听起来很简单,但它使我拉出我的头发(而且没有太多的左边)。



我在用户控件依赖项属性。该视图模型具有实现INotifyPropertyChanged接口的财产,正确地调用PropertyChanged事件



一些问题:
1)如何拿起更改它的ViewModel属性和领带的依赖项属性没有打破MVVM分离?到目前为止,我已经成功地做​​到这一点的唯一方法是分配的ViewModels PropertyChanged事件中的控件后面的代码,这绝对不是MVVM。



2)使用上述软糖,我可以依赖属性揭开序幕其PropertyChangedCallback,但绑定到它的控制范围之外什么都不拿起变化。



必须有一个简单的方法来做到这一切。请注意,我还没有发布任何代码在这里 - 我希望不要用我现有的代码影响的答案。此外,你可能在这一切的笑反正...



罗布



确定,以澄清 - 示例代码:



用户控件的代码背后:

 公共静态的DependencyProperty NewRepositoryRunProperty = DependencyProperty.Register(NewRepositoryRun的typeof(INT)的typeof(GroupTree),
新FrameworkPropertyMetadata(空,新PropertyChangedCallback(OnNewRepositoryRunChanged)));
公众诠释? NewRepositoryRun
{
{返回(INT?)的GetValue(NewRepositoryRunProperty); }

{
的SetValue(NewRepositoryRunProperty,值);
}
}

私有静态无效OnNewRepositoryRunChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E)
{
如果(e.OldValue!= e.NewValue)
{

}
}

公共GroupTree()
{
的InitializeComponent();

GroupTreeVM VM =新GroupTreeVM();

this.DataContext = VM;

}



视图模型(GroupTreeVM.cs)

 私人诠释? _NewRepositoryRun; 
公众诠释? NewRepositoryRun
{
得到
{
返回_NewRepositoryRun;
}

{
_NewRepositoryRun =价值;
NotifyPropertyChanged();
}
}


解决方案

和现在我每周的不这样做的答案......



为您的用户控件创建一个视图模型是一个代码味道。



您遇到这个问题,因为那味道,而且它应该是你做错事的指示。



解决方案是沟的用户控件建立的虚拟机。如果它包含业务逻辑,它应该被移动到另一个视图模型合适的位置。



您应该想到用户控件作为只不过是一个更复杂的控制更多。请问文本框有自己的视图模型?号你的虚拟机的属性绑定到该控件的Text属性,控制显示其UI文本



想想MVVM用户控件这样的 - 对于每个模型,你有一个用户控件,并且它被设计在该模型向用户呈现数据。你可以使用任何你想显示用户的模式。是否需要一个按钮?露出你的用户控件一个ICommand属性,让你的业务逻辑绑定到它。请问您的业务逻辑需要知道里面的东西怎么回事?添加路由事件。



通常,在WPF中,如果你发现自己在问,为什么它伤害做的事,那是因为你不应该这样做。


I have a user control written in C# & WPF using the MVVM pattern.

All I want to do is have a property in the bound ViewModel exposed to outside of the control. I want to be able to bind to it and I want any changes to the property to be picked up by anything outside the control that is bound to the exposed value.

This sounds simple, but its making me pull out my hair (and there is not much of that left).

I have a dependency property in the user control. The ViewModel has the property implementing the INotifyPropertyChanged interface and is calling the PropertyChanged event correctly.

Some questions: 1) How do I pick up the changes to the ViewModel Property and tie it to the Dependency Property without breaking the MVVM separation? So far the only way I've managed to do this is to assign the ViewModels PropertyChanged Event in the Controls code behind, which is definitely not MVVM.

2) Using the above fudge, I can get the Dependency property to kick off its PropertyChangedCallback, but anything bound to it outside the control does not pick up the change.

There has to be a simple way to do all of this. Note that I've not posted any code here - I'm hoping not to influence the answers with my existing code. Also, you'd probably all laugh at it anyway...

Rob

OK, to clarify - code examples:

usercontrol code behind:

   public static DependencyProperty NewRepositoryRunProperty = DependencyProperty.Register("NewRepositoryRun", typeof(int?), typeof(GroupTree),
                                                                new FrameworkPropertyMetadata( null, new PropertyChangedCallback(OnNewRepositoryRunChanged)));
    public int? NewRepositoryRun
    {
        get { return (int?)GetValue(NewRepositoryRunProperty); }
        set
        {
            SetValue(NewRepositoryRunProperty, value);
        }
    }

    private static void OnNewRepositoryRunChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.OldValue != e.NewValue)
        {

        }
    }

    public GroupTree()
    {
        InitializeComponent();

        GroupTreeVM vm = new GroupTreeVM();

        this.DataContext = vm;

    }

Viewmodel (GroupTreeVM.cs)

   private int? _NewRepositoryRun;
    public int? NewRepositoryRun
    {
        get
        {
            return _NewRepositoryRun;
        }
        set
        {
            _NewRepositoryRun = value; 
            NotifyPropertyChanged();
        }
    }

解决方案

And now for my weekly "don't do that" answer...

Creating a ViewModel for your UserControl is a code smell.

You're experiencing this issue because of that smell, and it should be an indication that you're doing something wrong.

The solution is to ditch the VM built for the UserControl. If it contains business logic, it should be moved to an appropriate location in another ViewModel.

You should think of a UserControl as nothing more than a more complex control. Does the TextBox have its own ViewModel? No. You bind your VM's property to the Text property of the control, and the control shows your text in its UI.

Think of UserControls in MVVM like this--For each model, you have a UserControl, and it is designed to present the data in that model to the user. You can use it anywhere you want to show the user that model. Does it need a button? Expose an ICommand property on your UserControl and let your business logic bind to it. Does your business logic need to know something going on inside? Add a routed event.

Normally, in WPF, if you find yourself asking why it hurts to do something, it's because you shouldn't do it.

这篇关于脱发和MVVM用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆