This is a migrated thread and some comments may be shown as answers.

Ranges databinding in Custom Control

4 Answers 162 Views
Gauges
This is a migrated thread and some comments may be shown as answers.
Wenrong
Top achievements
Rank 1
Wenrong asked on 11 Jul 2014, 09:48 AM
Data binding doesn't work when the Gauge control is hosted inside a Custom Control (we need to use Custom control for better performance)

See sample code below, the Gauge in MainWindow binds fine with the Ranges, but not the Gauge inside the custom control.

MainWindow.xaml
<Window x:Class="GaugeTest.MainWindow"
        xmlns:local="clr-namespace:GaugeTest"
        Title="MainWindow" Height="638" Width="575">
    <StackPanel>
        <telerik:RadRadialGauge Name="PART_Gauge" Width="220" Height="220">
            <telerik:RadialScale Name="scale"
                                 RangeLocation="Outside"
                                 LabelRotationMode="None"
                                 Radius="0.93"
                                 Ranges="{Binding Ranges}">
 
                <telerik:RadialScale.Indicators>
                    <telerik:BarIndicator Name="radialBar"
                                          UseRangeColor="True"
                                          RangeColorMode="ProportionalBrush"
                                          StartWidth="0.06"
                                          telerik:ScaleObject.Location="Outside"
                                          telerik:ScaleObject.Offset="0.01*"
                                          Value="0" />
                </telerik:RadialScale.Indicators>
            </telerik:RadialScale>
        </telerik:RadRadialGauge>
        <local:RadialGaugeControl Width="220" Height="220" />
    </StackPanel>
</Window>

MainWindow.cs
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Gauge;
 
namespace GaugeTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            scale.SetCurrentValue(ScaleBase.RangesProperty, new GaugeRangeCollection());
 
            this.DataContext = new MainWindowViewModel();
        }
    }
 
    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            Ranges = new GaugeRangeCollection();
            AddRange(0, 30, Colors.Green);
            AddRange(30, 60, Colors.Yellow);
            AddRange(60, 100, Colors.Orange);
        }
 
        private void AddRange(double min, double max, Color color)
        {
            GaugeRange gr = new GaugeRange()
            {
                Min = min,
                Max = max,
                StartWidth = 0.01,
                EndWidth = 0.01,
                Background = new SolidColorBrush(color),
                IndicatorBackground = new SolidColorBrush(color),
                TickBackground = new SolidColorBrush(color),
                LabelForeground = new SolidColorBrush(color),
            };
            gr.PropertyChanged += (s, e) =>
            {
                if (e.PropertyName == "Background")
                {
                    // make sure they are in sync
                    gr.IndicatorBackground = gr.Background;
                    gr.TickBackground = gr.Background;
                    gr.LabelForeground = gr.Background;
                }
            };
            Ranges.Add(gr);
        }
 
        private GaugeRangeCollection _ranges;
        public GaugeRangeCollection Ranges
        {
            get
            {
                return _ranges;
            }
            set
            {
                _ranges = value;
                OnPropertyChanged(() => Ranges);
            }
        }
    }
}

RadialGaugeControl.cs
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
namespace GaugeTest
{
    public class RadialGaugeControl : Control
    {
        static RadialGaugeControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(RadialGaugeControl), new FrameworkPropertyMetadata(typeof(RadialGaugeControl)));
        }
    }
}

Theme\Generic.xaml
<ResourceDictionary
    xmlns:local="clr-namespace:GaugeTest">
 
 
    <Style TargetType="{x:Type local:RadialGaugeControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:RadialGaugeControl}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <telerik:RadRadialGauge Name="PART_Gauge" Width="220" Height="220">
                            <telerik:RadialScale Name="PART_Scale"
                                     RangeLocation="Outside"
                                     LabelRotationMode="None"
                                     Radius="0.93"
                                             Ranges="{Binding Ranges}">
 
                                <telerik:RadialScale.Indicators>
                                    <telerik:BarIndicator Name="radialBar"
                                              UseRangeColor="True"
                                              RangeColorMode="ProportionalBrush"
                                              StartWidth="0.06"
                                              telerik:ScaleObject.Location="Outside"
                                              telerik:ScaleObject.Offset="0.01*"
                                              Value="0" />
                                </telerik:RadialScale.Indicators>
                            </telerik:RadialScale>
                        </telerik:RadRadialGauge>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

App.xaml
<Application x:Class="GaugeTest.App"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.xaml" />
                <ResourceDictionary Source="/Telerik.Windows.Themes.Windows8;component/Themes/Telerik.Windows.Controls.DataVisualization.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

4 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 11 Jul 2014, 12:22 PM
Hi Wenrong,

It is very complicated and it is hard to reproduce the problem without your solution, but using just a code snippet you sent. Could you, please, open a support ticket and attach your solution for detail analysis?

Regards,
Andrey Murzov
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Paul
Top achievements
Rank 1
answered on 17 Sep 2014, 06:05 PM
Has there been a solution to this?

I am encountering a similar issue with using a Ranges binding in a Data Template.  the ranges don't show. 
<DataTemplate DataType="{x:Type local:Measure}">
                <telerik:RadRadialGauge MinWidth="200"
                                        MinHeight="200">
                    <telerik:RadialScale Ranges="{Binding  Path=Ranges}">
                        <telerik:RadialScale.Indicators>
                            <telerik:BarIndicator UseRangeColor="True"
                                                  RangeColorMode="Default"
                                                  EmptyFill="Transparent"
                                                  Background="Transparent"
                                                  StartWidth=".07"
                                                  EndWidth=".07"
                                                  telerik:ScaleObject.Location="OverOutside"
                                                  telerik:ScaleObject.Offset="0.01*"
                                                  Value="50"
                                                  HorizontalContentAlignment="Stretch"
                                                  VerticalContentAlignment="Stretch" />
                        </telerik:RadialScale.Indicators>
                    </telerik:RadialScale>
                </telerik:RadRadialGauge>
            </DataTemplate>
0
Martin Ivanov
Telerik team
answered on 18 Sep 2014, 12:20 PM
Hi Paul,

I already answered your question in a support ticket, but I am posting it also here so our community can benefit from it.

In order to resolve this you can create an attached property that will bind the Ranges collection in code. Here is an example:

public class GaugeUtilities
{
    public static IEnumerable GetRanges(DependencyObject obj)
    {
        return (IEnumerable)obj.GetValue(RangesProperty);
    }
 
    public static void SetRanges(DependencyObject obj, IEnumerable value)
    {
        obj.SetValue(RangesProperty, value);
    }
 
    // Using a DependencyProperty as the backing store for Ranges.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty RangesProperty =
        DependencyProperty.RegisterAttached("Ranges"typeof(IEnumerable),typeof(GaugeUtilities), new PropertyMetadata(null, OnRangesPropertyChanged));
 
    private static void OnRangesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        RadialScale scale = (RadialScale)d;
        var ranges = e.NewValue as GaugeRangeCollection;
        if (ranges != null)
        {
            var binding = new Binding() { Source = ranges };
            scale.SetBinding(ScaleBase.RangesProperty, binding);
        }
    }
}

<telerik:RadialScale local:GaugeUtilities.Ranges="{Binding ElementName=rbi,  Path=DataContext.Ranges, Converter={StaticResource conv}}">

Regards,
Martin
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Paul
Top achievements
Rank 1
answered on 18 Sep 2014, 12:21 PM
Thank you, the fix worked for my case.

Paul Montgomery
Tags
Gauges
Asked by
Wenrong
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Paul
Top achievements
Rank 1
Martin Ivanov
Telerik team
Share this question
or