0
votes

I got the problem that my DataTemplate (UserControl) has no DataContext. But I need the DataContext because I got a Drop-Event where I call the ViewModel.

I got a ItemsControl with an ItemTemplateSelector="{StaticResource PropertyDataTemplateSelector}"> where I load between two different UserControls.

When I set my breakpoint in the constructor of the UserControl, I cant see a DataContext.

My MainView Ressources

 <Window.Resources>
    <Converter:DecreaseIntConverter x:Key="DecreaseIntConv" />
    <Converter:PortalSlotConverter x:Key="PortalSlotConverter" />

    <DataTemplate  x:Key="SXUserControl"
                   DataType="{x:Type ViewModel:MainViewModel}">
        <Resources:SXUserControl />
    </DataTemplate>
    <DataTemplate x:Key="XSUserControl"
                  DataType="{x:Type ViewModel:MainViewModel}">
        <Resources:XSUserControl/>
    </DataTemplate>
    <Helper:PropertyDataTemplateSelector x:Key="PropertyDataTemplateSelector"
                                         SXUserControl="{StaticResource SXUserControl}"
                                         XSUserControl="{StaticResource XSUserControl}" />
</Window.Resources>

The ItemsControl in my MainView

 <ItemsControl DockPanel.Dock="Right"
                              Width="Auto"
                              ItemsSource="{Binding MachineList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                              ItemTemplateSelector="{StaticResource PropertyDataTemplateSelector}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Grid ShowGridLines="True"
                                  Helper:GridHelpers.RowCount="10"
                                  Helper:GridHelpers.ColumnCount="4"
                                  Helper:GridHelpers.StarColumns="0,1,2,3">
                            </Grid>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>

My ItemTemplateSelector:

 public class PropertyDataTemplateSelector : DataTemplateSelector
{

    public DataTemplate SXUserControl { get; set; }
    public DataTemplate XSUserControl { get; set; }


    public override DataTemplate
    SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is Machine)
        {
            Machine machineItem = item as Machine;

            if (machineItem.MachineType == MachineType.SX)
                return
                    SXUserControl;
            else
                return
                    XSUserControl;
                    //element.FindResource("XSUserControl") as DataTemplate;
        }
        return null;
    }

}
1
The control instance is first created, then the DataContext is set. So the DataContext is obviously set after the constructor has finished. If you need to access the DataContext as soon as it is set, attach a DataContextChanged event handler.Clemens
The control is instaced after DataContext is set. I checked it with breakpoints.ChopaChupChup
Sorry, that makes no sense at all. You can't set a property of something that was not created beforeClemens
I belive there has to be a bigger mistake in the code. When I check var a = this; and make a breakpoint, then I see at the Property "Parent = null"ChopaChupChup
Not sure what exactly you mean, but in the constructor, all properties have their default values. Move your code to an event handler that is called later (after construction has finished), i.e. the Loaded event. Or to an overridden method, like OnInitialized.Clemens

1 Answers

-2
votes

Now it works! Added to the constructor of UserControl

    public SXUserControl()
    {
        InitializeComponent();
        allowDropConverter = new AllowDropConverter();
        this.Loaded += new RoutedEventHandler(UserControl_Loaded); //!!!
    }

and the Event

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        Window parentWindow = Window.GetWindow(this);
        mainViewModel = (MainViewModel)parentWindow.DataContext;
    }

Thx to Clemens for let me rethink to use Events!