Reputation: 1958
WPF Binding Control Widths so they are always the same width
I would like to bind the width of a Window to the ActualWidth of a control on another window.
As I have acheived so far, it updates the width on only once on showing the window, but does not update as the source control changes width.
Window 1 with DockPanel control, which has the ActualWidth I wish to bind to (in practice there are multiple controls, but I've only put one DockPanel here for simplicity):
<Window x:Class="Testing1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Testing1"
mc:Ignorable="d"
Title="WindowWithControl" Height="350" Width="525" Initialized="Window_Initialized" Loaded="Window_Loaded" Closed="Window_Closed">
<Grid Name="gridMain">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<DockPanel Name="dockBindSource" Grid.Row="0" >
</DockPanel>
</Grid>
</Window>
Window 2 - This is the window I want to match the width of the control in the previous window.
<Window x:Class="Testing1.ProgressOverlay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Testing1"
mc:Ignorable="d"
Title="ProgressOverlay" Height="300" Width="300" ShowInTaskbar="False" Opacity="0.75" AllowsTransparency="True" WindowStyle="None">
<Canvas Name="canvasPB" />
</Window>
Code in cs to test binding the width here. I need to do this at runtime, beacuse at design time I do not know which control the window will be linked to.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ProgressOverlay po = new ProgressOverlay();
po.Owner = this;
Binding b1 = new Binding();
b1.Mode = BindingMode.OneWay;
b1.Source = this.dockBindSource.ActualWidth;
po.SetBinding(FrameworkElement.WidthProperty, b1);
po.Show();
}
All I've read about implementing binding is the requirement of INotifyPropertyChanged. I've used this before on custom classes, but not sure how to use on an existing control class.
I presume I need to raise a property change event of some sort in this part of the XML: <Canvas Name="canvasPB" />
Otherwise I'll give up on binding and just add a SizeChanged event to the Canvas, but throught there might be a cleaner way.
Upvotes: 2
Views: 1585
Reputation: 7306
Try this:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ProgressOverlay po = new ProgressOverlay();
po.Owner = this;
Binding b1 = new Binding("ActualWidth");
b1.Mode = BindingMode.OneWay;
b1.Source = this.dockFilterClient;
po.SetBinding(FrameworkElement.WidthProperty, b1);
po.Show();
}
The Binding's Source
property holds a reference to the source object of the binding, while its Path
references the (optionally nested) source property.
The Binding constructor with a string argument sets the Path
property, equivalent to
b1.Path = new PropertyPath("ActualWidth");
in your case.
Upvotes: 2
Reputation: 13458
I don't know why, but it seems the binding on Window.Width
is not working. Proposed workaround: set the window to SizeToContent="Width"
and bind the width to the window content (canvasPB
)
Binding b1 = new Binding("ActualWidth");
b1.Mode = BindingMode.OneWay;
b1.Source = this.dockBindSource;
po.canvasPB.SetBinding(FrameworkElement.WidthProperty, b1);
Upvotes: 3