【问题标题】:WPF Binding Control's widths at runtimeWPF 绑定控件在运行时的宽度
【发布时间】:2017-08-30 04:04:50
【问题描述】:

WPF 绑定控件宽度,所以它们总是相同的宽度

我想将一个窗口的宽度绑定到另一个窗口上控件的实际宽度。

到目前为止,它只在显示窗口时更新一次宽度,但不会随着源代码控制更改宽度而更新。

带有 DockPanel 控件的窗口 1,它具有我希望绑定到的 ActualWidth(实际上有多个控件,但为了简单起见,我在这里只放了一个 DockPanel):

<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 - 这是我想要匹配上一个窗口中控件宽度的窗口。

<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>

cs 中的代码在此处测试绑定宽度。我需要在运行时执行此操作,因为在设计时我不知道窗口将链接到哪个控件。

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();
}

我所读到的关于实现绑定的所有内容都是 INotifyPropertyChanged 的​​要求。我以前在自定义类上使用过它,但不确定如何在现有控件类上使用。
我想我需要在这部分 XML 中引发某种属性更改事件:&lt;Canvas Name="canvasPB" /&gt;
否则我将放弃绑定,只在 Canvas 中添加一个 SizeChanged 事件,但可能会有更简洁的方法。

【问题讨论】:

  • private void Window_Loaded(object sender, RoutedEventArgs e)代替private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
  • @Nobody 我更愿意链接以控制大小更改,但即便如此,在每个大小更改事件中创建一个新的绑定对象对我来说似乎还是很奇怪。使用这种方法,我倾向于使用以下代码:po.Width = dockBindSource.ActualWidth;

标签: c# wpf xaml data-binding


【解决方案1】:

我不知道为什么,但似乎Window.Width 上的绑定不起作用。建议的解决方法:将窗口设置为SizeToContent="Width",并将宽度绑定到窗口内容(canvasPB

Binding b1 = new Binding("ActualWidth");
b1.Mode = BindingMode.OneWay;
b1.Source = this.dockBindSource;
po.canvasPB.SetBinding(FrameworkElement.WidthProperty, b1);

【讨论】:

  • 谢谢。惊人的简单解决方案。很高兴知道 Window.Width 上的绑定不起作用!
  • 解决方案的第二部分是将其放入窗口xaml中,以便窗口宽度调整为画布宽度:SizeToContent="Width"
  • 是的,我第一件事就是冲进去的。最后阅读整个答案。另一个重要的事情是运行po.Show() before SetBinding(),否则在初始加载时将无法正确显示。
【解决方案2】:

试试这个:

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();
}

绑定的Source 属性包含对绑定的源对象 的引用,而其Path 引用(可选嵌套的)源属性

带有字符串参数的Binding构造函数设置Path属性,相当于

b1.Path = new PropertyPath("ActualWidth");

在你的情况下。

【讨论】:

  • 不,这不起作用。与其他代码的结果相同 - 在调整大小期间宽度不会更新。
  • 绑定必须是双向的。但是,这不适用于 ActualWidth,因为它是只读的。你应该有一个视图模型属性。
  • @Clemens 为什么选择 TwoWay?用户在代码中表达了 OneWay。它应该与 ActualWidth 一起使用。顺便说一句,如果实际行为必须是双向绑定,我同意 VM 是一种解决方案。
  • 不知道,它只是不适用于 OneWay 绑定。自己试试,例如通过绑定到主窗口中的滑块值。
  • 这就是为什么测试你在答案中发布的代码总是一个好主意。
猜你喜欢
  • 2011-08-17
  • 2011-06-14
  • 2012-06-15
  • 2017-12-31
  • 2013-10-07
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多