Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF MeterDouble RangeFill binding in DataTemplate

I am loading meters dynamically with an items control panel and formatting the data and style via data template.  The binding for the meter value and range works fine. 

 

I want to highlight a range on the meter scale that works like the WinForms ScaleRangeFill.

 

I read for the WPF controls, this must be done with ni:Primitives.  I followed an example shown for a guage.

 

I can manually code the Baseloine RelativeOffset and RelativeLength values, but they will not bind to a property of the current object handled by the data template.  Below is my XAML.

 

I cannot dynamically bind the Green range shown in this screen shot.  I can only hard code the values in the XAML.

 

What am I missing?

 

 

 

 

 

<!-- ////////////////////////////////////////////////////////// -->

<!-- Motor Block Meter1                                         -->

<!-- ////////////////////////////////////////////////////////// -->

<!—This style is located in an external styling xaml file, the binding for range is OK -->

    <Style x:Key="MotorBlockMeterStyle" TargetType="{x:Type ni:MeterDouble}">

        <Setter Property="Height" Value="Auto" />

        <Setter Property="Width" Value="Auto" />

        <Setter Property="Margin" Value="1,1,1,1" />

        <Setter Property="Range" Value="{Binding Range, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />

    </Style>

 

 

 

 

User control:

<UserControl xmlns:ni="http://schemas.ni.com/controls/2009/xaml/presentation"

             xmlns:niPrimitives="http://schemas.ni.com/controls/2009/xaml/presentation/primitives"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:local="clr-namespace:Auma.EMP.TestBench.UserControls"

             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"        

             x:Class="Auma.EMP.TestBench.UserControls.MotorBlockMeterView"

             xmlns:Custom="http://www.galasoft.ch/mvvmlight"

             mc:Ignorable="d" >

 

    <UserControl.Resources>

 

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="..\Styles\EMPTestBenchStyles.xaml"/>

            </ResourceDictionary.MergedDictionaries>

 

            <DataTemplate x:Key="MotorBlockMeterTemplate">

 

                <StackPanel>

                    <Label Content="{Binding Caption, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">

 

                    </Label>

                    <ni:MeterDouble

                    Value="{Binding Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

                    Style="{DynamicResource MotorBlockMeterStyle}"

                    >

                        <ni:MeterDouble.TrackDecorations>

                            <niPrimitives:RelativeRadialScalePanel

                                niPrimitives:RelativeRadialHostPanel.Edge="Inside"

                                niPrimitives:RelativePanel.RelativeWidth="1.0"

                                niPrimitives:RelativePanel.RelativeHeight="1.0"

                                niPrimitives:RelativePanel.RelativeHorizontalPosition="0.5"

                                niPrimitives:RelativePanel.RelativeHorizontalAlignment="Center"

                                ArcSweep="{Binding ScaleArc, RelativeSource={RelativeSource AncestorType=ni:MeterDouble}}"

                                >

<!— This is the Binding of the RelativeOffset and RelativeLength will not work here! -->

<!— The binding to a property of the current item handled by the DataTemplate is not working -->

<!— I can manually code values here, such as “0.5” but I cannot get a value to bind -->

<!— Is the DataContext changing in the Baseline element, and if so, do how do I get it back to the DataTemplate object? -->

 

                                <niPrimitives:Baseline

                                    

                                    RelativeOffset="{Binding RangeFillOffset, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

                                    RelativeLength="0.5"

                                   

                                    Stroke="#FF32CD32"

                                    StrokeThickness="40"

                                    StrokeEndLineCap="Flat"

                                    StrokeStartLineCap="Flat">

                                   

                                </niPrimitives:Baseline>

                            </niPrimitives:RelativeRadialScalePanel>

                        </ni:MeterDouble.TrackDecorations>

                    </ni:MeterDouble>

                </StackPanel>

 

            </DataTemplate>

 

 

        </ResourceDictionary>

    </UserControl.Resources>

 

 

    <StackPanel DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MotorBlockMeterView}}">

 

        <Border

            Style="{DynamicResource SwitchControlBottomBorderStyle}">

            <Grid

            

            HorizontalAlignment="Stretch"

            Height="Auto"

            VerticalAlignment="Top"

            Width="Auto">

                <Grid.ColumnDefinitions>

                    <ColumnDefinition></ColumnDefinition>

                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>

                    <RowDefinition></RowDefinition>

                </Grid.RowDefinitions>

 

                <ItemsControl Grid.Column="0" Grid.Row="0"

                            ItemsSource="{Binding Path=DataContext.MBMVM.Meters, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

                            ItemTemplate="{StaticResource MotorBlockMeterTemplate}"

                    >

                    <ItemsControl.ItemsPanel>

                        <ItemsPanelTemplate>

                            <StackPanel>

                            </StackPanel>

                        </ItemsPanelTemplate>

                    </ItemsControl.ItemsPanel>

                </ItemsControl>

            </Grid>

        </Border>

    </StackPanel>

</UserControl>

0 Kudos
Message 1 of 5
(3,212 Views)

The DataContext of the Baseline needs to inherit from the DoubleMeter.  Next, the RelativeOffset and RelativeLength binding needs to reference the DataContext!

 

DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ni:MeterDouble}}"

 

RelativeOffset="{Binding DataContext.RangeFillOffset, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 

 

RelativeLength="{Binding DataContext.RangeFillLength, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

0 Kudos
Message 2 of 5
(3,200 Views)

Hi wrmbrnr, 

 

Just to confirm, by changing the DataContext of the Baseline needs to inherit from the DoubleMeter and referencing the Relative Offset and RelativeLength bindings to DataContext are you seeing what you expect to see?

 

0 Kudos
Message 3 of 5
(3,179 Views)

Yes.

0 Kudos
Message 4 of 5
(3,175 Views)

Your diagnosis was correct: the numeric pointer controls use a custom data context in their template, which overrides the data context on the control for objects that get hosted in the template (like track decorations).

 

To restore the data context, you just need to bind it through from the parent control, exactly like scale arc is set on the scale panel:

...
ArcSweep="{Binding ScaleArc, RelativeSource={RelativeSource AncestorType=ni:MeterDouble}}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ni:MeterDouble}}"
>
...
~ Paul H
0 Kudos
Message 5 of 5
(3,156 Views)