rayzinnz
rayzinnz

Reputation: 1958

WPF Binding Control's widths at runtime

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

Answers (2)

Mario Vernari
Mario Vernari

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

grek40
grek40

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

Related Questions