views:

28

answers:

0

Hello,

In my WPF app I have the following user controls:

<UserControl Name="UCOperand" ...>   
...
</UserControl>

<UserControl Name="UCOperation" ...>
   <ItemsControl Name=ic_items>...</ItemsConrol>
</UserControl>

The UCOperation user control can contain UCOperand user controls in it's "ic_items" ItemsControl. Now I have a design panel ItemsControl which can contain both of the user controls: UCOperand or UCOperation:

<ItemsControl Name="ic_design" ItemsSource={Binding Path=Components, Mode=OneWay} TargetUpdated="ic_design_TargetUpdated">  
...
</ItemsControl>

So, the "ic_design" is bound to the Components property of a VM class but I also need a reference to each of the user controls created for each item in the Components list. The Components list contains VM objects (UCOperandViewModel or UCOperationViewModel) which, when rendered on the view, will be either UCOperand or UCOperation. The "ic_design_TargetUpdated" event handler looks like this:

void ic_design_TargetUpdated (object sender, DataTransferEventArgs e)
{
   foreach (Object it in ic_design.Items)
      if (!_components.ContainsKey (it))
      {
         var el = ic_design.ItemContainerGenerator.ContainerFromItem (it) as FrameworkElement;

         addedUC = Helper.FindVisualChild<UCOperation> (el);

         // decide which UserControl we have to add to the _components list
         if (addedUC != null)
         {
            var vMax = _components.Values.Max (x => (x.RenderTransform as TranslateTransform).Y + x.ActualHeight);

            addedUC.RenderTransform = new TranslateTransform (8.0, vMax + 6);
         }
         else
            addedUC = Helper.FindVisualChild<UCOperand> (el);

         _components.Add (it, addedUC as SelectableUserControl);

         ComponentEvents.AddComponentChangedEventHandler (addedUC, ComponentChanged_EventHandler);

         addedUC.Loaded +=
            (_s, _e) => ComponentEvents.RaiseComponentChangedEvent (_s as DependencyObject, true);     
     }  
}  

So, I add "addedUC" to the "_components" list which stores every user control created. I associate the event handler "ComponentChanged_EventHandler" to each user control because I want to update the layout each time a user control is moved, resized or deleted. In the last statement above I raise the event because I want the layout to be updated when a new control is added to the panel. In the case when an UCOperand is added everything works fine, however when I add an UCOperation, the Loaded event doesn't get called (the last statement above). I tried to add the event handler in the constructor of the UCOperation but in that case the Loaded event gets called before the TargetEvent is fired and in that case ComponentEvents.AddComponentChangedEventHandler is not yet called for the user control. The main problem, as I figured it out is that the UCOperation user control's height is not calculated neither when the Loaded event is fired, nor in the "ic_design_TargetUpdated" method. So the "ComponentChanged_EventHandler" method cannot properly do its job. All user controls are added to the design panel every time but the UCOperation user control has no proper height until I select it with the mouse from the end user view.

Any help is really really appreciated. Thanks in advance.