Binding Problem

Apr 19, 2012 at 12:56 PM
Edited Apr 19, 2012 at 1:04 PM

Hello

I have an normal Combobox.

<ComboBox     ItemsSource="{Binding Components}"
              SelectedItem="{Binding ActiveComponent}" />

Components is an ObservableCollection<Unit> Property

I choose an value in the combobox. If the ActiveComponet is a normal property the set method is called.

If the ActiveComponent is an Catel property

        public Unit ActiveComponent
        {
            get { return GetValue<Unit>(ActiveComponentProperty); }
            set { SetValue(ActiveComponentProperty, value); }
        }
 
        public static readonly PropertyData ActiveComponentProperty= RegisterProperty("ActiveUnitCatel"typeof(Unit), null);

 

the set method is not called?!

Coordinator
Apr 19, 2012 at 12:57 PM
Edited Apr 19, 2012 at 12:58 PM

Don't you get an exception in your output window? The ActiveComponent is of tye Unit, while the collection is a list of strings.

Apr 19, 2012 at 1:04 PM

Sorry. That was only a copy past error. I make the example for here easier. So thats not the propblem. So i change it above.

Apr 19, 2012 at 1:48 PM

Any other idea. Or should i make an example?

Coordinator
Apr 19, 2012 at 1:49 PM

Please create an example, the only thing I can think of is that the mode should be set to TwoWay, but you probably already checked that. Also, if there is nothing special in the output window, I need a repro.

Apr 19, 2012 at 2:01 PM

This is in the outputwindow when i choose a value:

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')
03:59:40:756 => [DEBUG] [Catel.MVVM.ViewModelBase] A view model ('Configurator.ViewModels.PlaceViewModel') the current view model ('Configurator.ViewModels.RecipeBoxViewModel') is interested in has changed a property ('ActiveUnitCatel')
System.Windows.Data Information: 40 : BindingExpression path error: 'Name' property not found for 'object' because data item is null.  This could happen because the data provider has not produced any data yet. BindingExpression:Path=Name; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 19 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=Name; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=Name; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=Name; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'NoTarget' (type 'Object')

Coordinator
Apr 19, 2012 at 2:11 PM

Ok, please create a repro and a new issue where you can attach it to. Then I can take a look at it this tonight or tomorrow night.

Apr 20, 2012 at 7:30 AM
Edited Apr 20, 2012 at 7:30 AM

Ok i created a repro:

http://catel.codeplex.com/workitem/7122

Coordinator
Apr 20, 2012 at 6:07 PM

Fixed, the type descriptors for dynamic view model properties directly called SetValue/GetValue. This isn't wrong, but could cause some weird situations (such as yours). Therefore, I now let it always call the property on the view model if it exists. It will still call SetValue directly for dynamic properties.

Apr 20, 2012 at 8:56 PM
Edited Apr 20, 2012 at 8:57 PM

I have an issue similar to this and wanted to see if your fix will address my issue.  If so, when will the fix be available for download via NuGet?

I have a ComboBox on a view that is bound to a Catel property.  When the selection changes I want to reload my data.  I am attempting to do it like this:

(From xaml)

<ComboBox ItemsSource="{Binding ProviderList}" DisplayMemberPath="ProviderName" SelectedValuePath="ProviderId" SelectedValue="{Binding ProviderFilter, UpdateSourceTrigger=PropertyChanged}" />

(From view model which inherits from ViewModelBase)

public int? ProviderFilter{

    get { return GetValue<int?>(ProviderFilterProperty); }

    set { SetValue(ProviderFilterProperty, value);

    LoadData();

}

public static readonly PropertyData ProviderFilterProperty = RegisterProperty("ProviderFilter", typeof(int?), null);

If I put a break point on the set portion of the property, it only hits if I set the property value through code.  If I make a selection using the combo which is bound, I can verify that the property value is getting changed, but the break point never hits and therefore my LoadData method doesn't get called.

Coordinator
Apr 21, 2012 at 5:42 AM

I just started the release process. It takes appr. 20 minutes to complete (uploading nuget packages with source takes a long time). The new version will be 3.0.1204210735-beta.

However, it is recommended to not write custom code in the setter just for the sake of property change notification. You have 2 recommended options:

1) Override the OnPropertyChanged

2) Change your property registration:

public static readonly PropertyData ProviderFilterProperty = RegisterProperty("ProviderFilter", typeof(int?), null, (sender, e) => ((YourViewModel)sender).OnFilterChanged(e));

private void OnFilterChanged(PropertyChangedEventArgs e)
{
    LoadData();
}

Coordinator
Apr 21, 2012 at 6:07 AM

Update: beta is published

Apr 23, 2012 at 3:14 PM

Is this also how you recommend raising property changed events for calculated properties?  For example, let's say I have an observable collection property and a property that gives the count of items in the collection.  Whenever the collection changes I need to notify listeners that the count property has changed as well.

Coordinator
Apr 23, 2012 at 3:16 PM

No, because that is not a Catel property. In such a case, you will need to subscribe to the collection.CollectionChanged event (you can use the WeakEventListener for this to prevent memory leaks), then raise it manually.

So, this is only recommended for catel properties.