How do I set custom positions for user controls in an itemtemplate in WPF?

111 Views Asked by At

This is a follow-up question to my previous question regarding dependency properties.

I have a custom user control that acts as a Status Indicator for an HMI view (a few concentric circles that have different colours depending on some PLC state data). These status indicators take their state data from an items source and this is applied to an item template in my view. Following Gaz's advice for using an ItemsControl with an ItemsSource and ItemsTemplate, I am able to cleanly configure a collection of data to a custom user control Status Indicator and thus, I can draw to the screen a bunch of status indicators based on my items source List <DigitalIOAssignment> that is available in my viewmodel. This class object describes the state of the Status Indicator (engaged, interlocked etc) as well as a componentID that describes which item on a P&ID it is displaying information for. For some additional context, because I am reading my component status from a PLC, it is convenient in my use-case to read an entire array of status data whether a component is assigned to it or not for a given project. As a result, my List <DigitalIOAssignment> has a property that identifies whether a component is actually used or not and sets a visibility flag in the data template. This all works correctly.

My problem: I need to be able to position each status indicator on a P&ID in an arbitrary location so that to the user, it actually conveys information about a given component which may be located anywhere on the view. Initially, I just dragged new UserControls into my view and the margin values are where I'd like the object to be displayed. To correlate this to a particular DigitalIOAssignment object in the itemssource, I thought it would be convenient to name each UserControl with a string that I could check against the itemsource property DigitalIOAssignment.componentID and if the UserControl's name equals the componentID property, to draw the user control at the margin value I specified for that specific user control object. The ultimate goal here is to be able to create status indicators for an HMI relatively quickly; ie. Drag a StatusIndicator to the view, name the usercontrol the same component ID, and rest assured that the List <DigitalIOAssignment> will carry the correct information to the view.

<ItemsControl x:Name="DigitalInputStatusIndicatorDisplay"
              ItemsSource="{Binding privateDigitalInputAssignments}"
              ItemTemplate="{StaticResource StatusIndicatorDataTemplate}">
</ItemsControl>
<UserControls:StatusIndicator x:Name="DI_99VLV0123"                                      
                              Height="18" Width="18"
                              Margin="106,144,0,0"
                              HorizontalAlignment="Left" VerticalAlignment="Top"/>

Obviously this does nothing as written other than draw an ItemsControl for each privateDigitalInputAssignment based on the StatusIndicatorDataTemplate and draw an un-wired StatusIndicator at the margin described above.

I don't know how to proceed from this to compare x:Name of the UserControls:StatusIndicator that I place in my view to the itemssource and, if it matches the componentID property, to assign the margin listed above as well. My intuition still says that data triggers are needed but I cannot seem to figure how how/where to incorporate these. Can someone please give some advice?

0

There are 0 best solutions below