I have created a custom control which displays a number pad. The control has a dependency property (ButtonWidth) which sets the key size for all keys in the number pad. When the property changes all child buttons are enumerated and their Height and Width properties are updated.
At design time this works fine. I can change the property and the number pad display changes accordingly.
However at runtime the number pad is created but the button widths are not updated. I added a button which set the width in the Click event and this worked.
public static readonly DependencyProperty ButtonWidthProperty =
DependencyProperty.Register("ButtonWidth",
typeof(int),
typeof(VirtualKeyboard),
new FrameworkPropertyMetadata(40,
FrameworkPropertyMetadataOptions.AffectsArrange |
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.AffectsParentArrange,
OnButtonWidthPropertyChanged, OnCoerceButtonWidthProperty),
OnValidateButtonWidthProperty);
public int ButtonWidth
{
get { return (int)GetValue(ButtonWidthProperty); }
set { SetValue(ButtonWidthProperty, value); }
}
private static void OnButtonWidthPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("VK width");
VirtualKeyboard control = source as VirtualKeyboard;
int newVal = (int)e.NewValue;
control.UpdateButtons();
}
private static object OnCoerceButtonWidthProperty(DependencyObject sender, object data)
{
return data;
}
private static bool OnValidateButtonWidthProperty(object data)
{
return data is int;
}
public VirtualKeyboard()
{
Console.WriteLine("VK constr");
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
isCaps = true;
SetKeys();
UpdateButtons(); // this is where the current ButtonWidth property
// is read and the button width set
}
private void UpdateButtons()
{
Console.WriteLine("VK bw=" + ButtonWidth);
foreach (Button button in FindVisualChildren<Button>(this))
{
button.Width = button.Height = ButtonWidth;
}
}
What I noticed is that if I also set the Content property of a button this seems to force a re-layout of the control.
What am I doing wrong here? Why does it work at design time but not at run time?
Try doing your updating of the
WidthandHeightof your Buttons after the custom control has been loaded i.e. in theLoadedevent….not in your OnInitialized….because you need to wait for the template to be applied and the buttons to be created and in your visual tree.