I'm struggling to get my head around dependency properties in WPF, maybe because the use case I'm looking for is very specific and not well documented.
What I have is a custom control that looks like this (please do ignore all the terrible code, it is temporary!):
<UserControl x:Class="HydroAccessory.Controls.FillGraph"
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:HydroAccessory.Controls"
mc:Ignorable="d"
SizeChanged="FillGraph_SizeChanged"
d:DesignHeight="200" d:DesignWidth="300">
<Grid>
<TextBlock x:Name="PercentageTB" Text="Fill Percentage: 0%" />
</Grid>
I call it inside my main window like this:
<controls:FillGraph x:Name="HydroModel" />
and the code inside the control is as follows:
using System;
using System.Windows;
using System.Windows.Controls;
namespace HydroAccessory.Controls
{
public partial class FillGraph : UserControl
{
private float percentage;
public float Percentage
{
get
{
return percentage;
}
set
{
percentage = value;
PercentageTB.Text = String.Format("Fill Percentage: {0}", percentage.ToString() + "%");
}
}
public FillGraph()
{
InitializeComponent();
}
}
}
All that I want to be able to do is say in my custom control call in the main window:
<controls:FillGraph x:Name="HydroModel" Percentage="{Binding FillPercentage}" />
(Where FillPercentage is something in another script that you don't need to worry about). The control will be expanded, so it needs to stay as a custom control. I understand I may need dependency properties, but after trying many different ways I cannot figure out how to do this seemingly simple task. Help is appreciated.
There isn't a dependency property in your code.
This is a dependency property:
As Ayyappan Subramanian suggests, the
propdp
snippet in Visual Studio will help create the boilerplate. Just be careful with the parameters you pass toDependencyProperty.Register()
, and make sure the default value you pass tonew PropertyMetadata()
is the correct type.0.0f
is a float. If you pass integer0
for afloat
property, it'll throw an exception at runtime.The regular property
public float Percentage
here is optional. It's just there for your code to use. XAML won't ever touch it at all (put breakpoints in the getter and setter if you doubt me). That's part of what's special about dependency properties.And here's how to use it in your usercontrol XAML. Note the
StringFormat
parameter to the binding.Note: If your percentage is expressed in the range 0 to 1 rather than 0 to 100, use the
p
percent format instead. We'll usep2
for two digits after the decimal point. We omit the%
because the format string provides that.This XAML from your question is fine just as it is, assuming that the viewmodel has a
FillPercentage
property and correctly implementsINotifyPropertyChanged
: