开发者

Binding properties in two viewmodels in a two way manner

开发者 https://www.devze.com 2023-03-02 20:00 出处:网络
I\'m starting Caliburn Micro development and I have thought of an architecture where a viewmodel has properties, injected by MEF, which are other viewmodels. That way I can use contentcontrols in the

I'm starting Caliburn Micro development and I have thought of an architecture where a viewmodel has properties, injected by MEF, which are other viewmodels. That way I can use contentcontrols in the view to position them the way I want.

 public class ContactsProfileViewModel : Conductor<IContentItem>, IContactsModuleViewModel,      IModule, IPartImportsSatisfiedNotification
{
    private string name;
    private string nameCaption;
    private ISingleLineTextContentItem firstName;
    private ISingleLineTextContentItem lastName;

    public ContactsProfileViewModel()
    {
        this.DisplayName = "Contact Tab";
    }


    public string Name
    { 
        get
        {
            return this.name;
        }
        set
        {
            this.name = value;
            this.NotifyOfPropertyChange(() => Name);
        }
    }
    public string NameCaption 
    { 
        get
        {
        开发者_开发百科    return this.nameCaption;
        }
        set
        {
            this.nameCaption = value;
            this.NotifyOfPropertyChange(() => NameCaption);
        }
    }

    [Import(typeof(ISingleLineTextContentItem))]
    public ISingleLineTextContentItem FirstName
    {
        get { return this.firstName; }
        set 
        { 
            this.firstName = value;
            this.NotifyOfPropertyChange(() => FirstName);
        }
    }

    [Import(typeof(ISingleLineTextContentItem))]
    public ISingleLineTextContentItem LastName
    {
        get { return this.lastName; }
        set
        {
            this.lastName = value;
            this.NotifyOfPropertyChange(() => LastName);
        }
    }

The viewmodel of SingleLineTextContentItem looks like this:

[Export(typeof(ISingleLineTextContentItem))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class SingleLineTextContentItemViewModel : PropertyChangedBase, ISingleLineTextContentItem
{
    private string textBoxText;
    private string caption;

    public string TextBoxText
    {
        get { return textBoxText; }
        set 
        { 
            textBoxText = value;
            this.NotifyOfPropertyChange(() => TextBoxText);
        }
    }

    public string Caption
    {
        get { return caption; }
        set 
        {
            this.caption = value;
            this.NotifyOfPropertyChange(() => Caption);
        }
    }
}

Now, I need a way to bind the NameCaption property to the Caption property in a two-way manner. Is that possible? I'm I on the right track with this or is there a better way to do this?

Thanks,

Roland


What I do is instead of having a backing field just route to the other view model

public string NameCaption 
{ 
    get
    {
        return FirstName.Caption;
    }
    set
    {
        FirstName.Caption = value;
        this.NotifyOfPropertyChange(() => NameCaption);
    }
}

However if the Caption property on the ISingleLineTextContentItem can get set independently then you need to register changes on the event and have the view model listen to changes. So instead you need somthing along the lines of:

public string NameCaption 
{ 
    get
    {
        return FirstName == null ? string.Empty : FirstName.Caption;
    }
    set
    {
        if(FirstName != null)
           FirstName.Caption = value;
    }
}

[Import(typeof(ISingleLineTextContentItem))]
public ISingleLineTextContentItem FirstName
{
    get { return this.firstName; }
    set 
    { 
        if(this.FirstName != null)
            this.FirstName.PropertyChanged -= FirstNameChanged;

        this.firstName = value;

        if(this.FirstName != null) 
           this.FirstName.PropertyChanged += FirstNameChanged;

        this.NotifyOfPropertyChange(() => FirstName);
        this.NotifyOfPropertyChange(() => NameCaption);
    }
}

private void FirstNameChanged(object sender, PropertyChangedEventArgs e)
{
    if(e.PropertName == "Caption")
        this.NotifyOfPropertyChange(() => NameCaption);
}

Since either the Caption property or the FirstName property can change then we need to raise the event in the FirstName property and in the handler.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号