ElGaucho
ElGaucho

Reputation: 408

Binding ProgressBar in CustomControl seems not to work

I got a customcontrol that contains a ProgressBar among other elements.

<ProgressBar Value="{TemplateBinding CurrentProgress}"
             MinValue="{TemplateBinding MinValue}"
             MaxValue="{TemplateBinding MaxValue}"/>

<Label Content="{TemplateBinding CurrentProgress}"/>

In my .cs File, i defined all of these properties like this:

#region MaxProgress
public int MaxProgress
{
    get { return (int)GetValue(MaxProgressProperty); }
    set { SetValue(MaxProgressProperty, value); }
}

public static readonly DependencyProperty MaxProgressProperty =
        DependencyProperty.Register("MaxProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(1000, FrameworkPropertyMetadataOptions.AffectsRender)); 
#endregion

#region CurrentProgress
public int CurrentProgress
{
    get { return (int)GetValue(CurrentProgressProperty); }
    set { SetValue(CurrentProgressProperty, value); }
}

public static readonly DependencyProperty CurrentProgressProperty =
    DependencyProperty.Register("CurrentProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(50, FrameworkPropertyMetadataOptions.AffectsRender)); 
#endregion

#region MinProgress
public int MinProgress
{
    get { return (int)GetValue(MinProgressProperty); }
    set { SetValue(MinProgressProperty, value); }
}

public static readonly DependencyProperty MinProgressProperty =
    DependencyProperty.Register("MinProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion

Binding those values to the label as shown above works fine, but apparently those bindings do not work for my ProgressBar. What i have tried so far:

Any hints what could cause this?

Upvotes: 1

Views: 58

Answers (1)

Rhys
Rhys

Reputation: 4589

Answer based on your question

The binding method you should use in this situation is Value="{Binding CurrentProgress, RelativeSource={RelativeSource AncestorType={x:Type GameFlowControl}}}". This traverses the visual tree upwards finding the first GameFlowControl control, then binding to the path from this relative position.

An Alternative

As an alternative if you are not utilizing the DataContext in the UserControl for any other purpose you could use the shorter method of binding.

Firstly you would need to assign the DataContext to the derived UserControl reference using something like this:-

    public GasFlowControl()
    {
        InitializeComponent();

        DataContext = this;  //Set the DataContext to point to the control itself

    }

Then your binding can be simplified down to this:-

    <ProgressBar Value="{Binding CurrentProgress}"
         MinValue="{Binding MinValue}"
         MaxValue="{Binding MaxValue}"/>

    <Label Content="{Binding CurrentProgress}"/>

To answer your confusion

Added Breakpoints to the getters of those properties, they were not triggered (which confuses me a lot!)

The reason you did not get any breakpoints triggering for property Getters and Setters is that the WPF framework does not use them. It internally calls GetValue(CurrentProgressProperty); and SetValue(CurrentProgressProperty, value); directly. They are there only for your convenience to include in your code and have the convenience of type casting and thus type checking when compiling.

If your code does not use them then they will never be called at all.

Upvotes: 2

Related Questions