Acces from Usercontrol to viewmodel

Topics: Questions
Jun 13, 2013 at 11:46 AM
Hello

I use an catel:usercontrol with viewmodel generation.

when binding from an control inside the usercontrol to a property in viemodel everything works fine.
<StackPanel Visibility={Binding Visibility} />
but when i want to bind the property visibility direct in the usercontrol.
<catel:UserControl Visibility={Binding Visibility}>
</catel:UserControl>
its not possible.
Jun 13, 2013 at 12:33 PM
Take a look at this documentation, it explains it all.
Jun 13, 2013 at 12:58 PM
Oh.

Is it correct: The following code is in the layer: "UserControl with outside DataContext"
<catel:UserControl Visibility={Binding Visibility}>
</catel:UserControl>
So, how is it possible to hide the usercontrol with an property in the viewmodel? I can't find an solution in the given documentation.
Jun 13, 2013 at 12:59 PM
You might want to try:

<catel:UserControl Visibility={Binding ViewModel.Visibility}>
</catel:UserControl>
Jun 13, 2013 at 3:44 PM
Hm. Ok.

I added this one
    <UserControl.Visibility>
        <Binding Converter="{StaticResource ColapsedVisibilityConverter}" Path="ViewModel.IsVisible" />
    </UserControl.Visibility>
Because I need an converter. So I added it below of the </UserControl.Resources>.

But it don't works. I don't know why.
Jun 13, 2013 at 4:26 PM
Sorry, my bad:

<catel:UserControl Visibility={Binding RelativeSource=Self, Path=Visibility}>
</catel:UserControl>
Jun 14, 2013 at 6:54 AM
Edited Jun 14, 2013 at 7:08 AM
Hello again.

Now I get an exception:
{"'Set property 'System.Windows.Data.Binding.RelativeSource' threw an exception.' Line number '8' and line position '20'."}
{"Unable to cast object of type 'System.String' to type 'System.Windows.Data.RelativeSource'."}
Edit:

Oh.

Correct:
RelativeSource="{RelativeSource Self}"
and the whole line with converter:
    <catel:UserControl.Visibility>
        <Binding Converter="{StaticResource CollapsedVisibilityConverter}"
                 Path="IsVisible"
                 RelativeSource="{RelativeSource Self}" />
    </catel:UserControl.Visibility>
Thanks.
Jun 14, 2013 at 7:00 AM
Edited Jun 14, 2013 at 7:16 AM
Its still not working.

Now my Control is always hidden. No matther of the value of the property.

Edit: Now the real correct implementation :-)
    <catel:UserControl.Visibility>
        <Binding Converter="{StaticResource B2VConverter}"
                 Path="ViewModel.IsVisible"
                 RelativeSource="{RelativeSource Self}" />
    </catel:UserControl.Visibility>
Jun 17, 2013 at 2:05 PM
Hello again.

One more problem. Take a look at this implementation.
...
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Views:StationDetailView />  <!-- thats the usercontrol -->
                    </DataTemplate>
                </ListBox.ItemTemplate>

              <!-- and that's the way to hide an disable an item-->
              <!-- but here the binding didn't work-->
              <!-- IsVisible ist the property in the viewmodel  of StationDetailView --> 
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=ViewModel.IsVisible, RelativeSource={RelativeSource Self}}" Value="False">
                                <Setter Property="Visibility" Value="Collapsed" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.ItemContainerStyle>
...
Jun 20, 2013 at 7:52 AM
Sorry again. Im still on this problem. I try a lot of thinks but no chance to get access in ItemContainerStyle to the viewmodel. Access to model is not a problem. But my property is in the viewmodel :-(

Do you have any ideas?
Jun 20, 2013 at 8:10 AM
You can always give the parent listbox a name. Then use ElementName.
Jun 20, 2013 at 8:35 AM
Yes I know. But that don't solve my problem. I don't need acces to the viewmodel of the Listbox. I need access to the viewmodel of every item in the Listbox.
Jun 20, 2013 at 8:50 AM
I don't know.
Jun 20, 2013 at 9:01 AM
Ok. And now what to do?

I wan't do disable or hide a Item in an listbox: Take a ook at this page:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/ce058392-45bf-4a43-89e8-170d6d58a9ef/disabling-a-listbox-item-in-the-data-template


When I have acces to the model. Is it not possible to get the viewmodel of the model in xaml.
Jun 20, 2013 at 11:14 AM
I don't know. I think this is a WPF question in general, not a Catel one. Maybe you should ask this on StackOverflow.
Jun 20, 2013 at 12:32 PM
No it is not general problem of wpf.
Because:

In the ItemContainerStyle you have access direct to the datacontext. Thats model or viewmodel depends on what you set as datacontext.
With catel you have the problem that the datacontext is replaced from model to viewmodel but to late.

I tried the following. I added an converter:

ModelToViewModelConverter:

<ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <!-- Binding = Access to Datacontext -->
                    <DataTrigger Binding="{Binding Converter=ModelToViewModelConverter}" Value="False">  
                        <Setter Property="Visibility" Value="Collapsed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
</ListBox.ItemContainerStyle>
    public class ModelToViewModelConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var manager = ServiceLocator.Default.ResolveType<IViewModelManager>();
            var vm = manager.GetViewModelsOfModel(value).SingleOrDefault();
            return vm;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
If you debug you see that the viewmodel for the item in the Listbox is not createt yet.
Jun 21, 2013 at 8:47 AM
Is it not possible to generate all ViewModels OnStartup. Same like in the TabUserControlExtended which I have suggested.
Jun 21, 2013 at 11:34 AM
The VM is not created at construction time yet, but as soon as it loads the VM, it should change. Are you sure the Binding without path is the right path?
Jun 21, 2013 at 2:29 PM
The Binding without the path is the path to the datacontext of the StationDetailView. So at this time its the model. And its correct. I see it in the Converter. It is StationModel. So later datacontext is changed to StationViewModel.

I just need to hide an listitem with binding to a property in viewmodel. Every Item is an catel:usercontrol. If I hide only the usercontrol its not visible any more but the item itself is still there an I can select it.
Jun 24, 2013 at 7:56 AM
Should I make a repro to show what I mean and add an isue?
Jun 24, 2013 at 6:24 PM
yes please.
Jun 26, 2013 at 7:03 PM
Ok. Added an issue. Don't know which type of issue to select. I choose Bug. Maybe you can change this:

https://catelproject.atlassian.net/browse/CTL-104
Jun 26, 2013 at 7:47 PM
Thanks. Don't worry about the type. I always double check all fields before starting progress on an issue.