0
votes

Hi i have an application Wpf with Caliburn Micro and MongoDb i have a collection like this

[Bson IgnoreExtraElements]
public class ResourceCollection : CompanyModel
{
    public ResourceCollection(string Vat) : base(Vat)
    {
    }

    private long _ResourceID;

    public long ResourceID
    {
        get { return _ResourceID; }
        set { _ResourceID = value; }
    }

    private string _Description;

    public string Description
    {
        get { return _Description; }
        set
        {
            _Description = value;
            NotifyOfPropertyChange(() => Description);
        }
    }
}

where CompanyModel inherit from PropertyChangedBase, and i have a view model:

public class ResourceCreateViewModel : Screen
{
    private IWindowManager _windowManager;
    private readonly AppConnection _appConnection;
    private readonly ResourceRepository _resourceRepository;

    private ResourceCollection _Resource;
    public ResourceCollection Resource
    {
        get
        {
            return _Resource;
        }
        set
        {
            _Resource = value;
            NotifyOfPropertyChange(() => Resource);
            NotifyOfPropertyChange(() => CanSave);
        }
    }
}

And this is my xaml

  <TextBox Text="{Binding Resource.Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="20" DockPanel.Dock="Right"></TextBox>

my problem is that when i change the value inside the texbox, the set of my viewmodel class not fire, how can i bind my class to the textbox?

Thank you in advance

1

1 Answers

0
votes

The reason it doesn't fire it is simple: the Resource object didn't get set, you only set a property on it. To solve this you could create a new property ResourceDescription and bind to that instead:

    public string ResourceDescription
    {
    get
    {
        return _Resource.Description;
    }
            set
            {
                _Resource.Description = value;
                NotifyOfPropertyChange(() => ResourceDescription);
                NotifyOfPropertyChange(() => Resource);
                NotifyOfPropertyChange(() => CanSave);
            }
    }

Xaml:

<TextBox Text="{Binding Resource.Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

But this comes with its own problems because changes in the viewmodel no longer update your view. Instead you can subscribe to the resources PropertyChanged event:

private ResourceCollection _Resource;
public ResourceCollection Resource
{
    get
    {
        return _Resource;
    }
    set
    {
        if(_Resource != null)
        {
            _Resource.PropertyChanged -= ResourcePropertyChanged;
        }

        _Resource = value;

        if(_Resource != null)
        {
            _Resource.PropertyChanged += ResourcePropertyChanged;
        }

        NotifyOfPropertyChange(() => Resource);
        NotifyOfPropertyChange(() => CanSave);
    }
}

private void ResourcePropertyChanged(object sender, EventArgs e)
{
    //you might be able to do something better than just notify of changes here
    NotifyOfPropertyChange(() => Resource);
    NotifyOfPropertyChange(() => CanSave);
}

This can get complicated very quickly, especially if you are subscribing to properties nested deeper in the object graph.