【问题标题】:Problems with binding to Window Height and Width绑定到窗口高度和宽度的问题
【发布时间】:2011-02-10 01:02:48
【问题描述】:

当我尝试将窗口的高度和宽度绑定到我的视图模型中的属性时,我遇到了一些问题。这是一个小示例应用程序来说明问题。这是 app.xaml.xs 中的代码

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
       base.OnStartup(e);
        MainWindow mainWindow = new MainWindow();
        MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
        mainWindow.DataContext = mainWindowViewModel;
        mainWindow.Show();
    }
}

这是 MainWindow.xaml:

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="{Binding WindowHeight}" 
        Width="{Binding WindowWidth}"
        BorderThickness="{Binding WindowBorderThickness}">
</Window>

这是视图模型:

public class MainWindowViewModel
{
    public int WindowWidth { get { return 100; } }
    public int WindowHeight { get { return 200; } }
    public int WindowBorderThickness { get { return 8; } }
}

程序启动时会调用 WindowHeight 和 WindowBorderThickness(但不包括 WindowWidth)的 getter,因此窗口的高度和边框设置正确,但宽度设置不正确。

然后我添加按钮,该按钮将为所有属性触发 PropertyChanged,因此视图模型现在看起来像这样:

public class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void TriggerPropertyChanges()
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("WindowWidth"));
            PropertyChanged(this, new PropertyChangedEventArgs("WindowHeight"));
            PropertyChanged(this, new PropertyChangedEventArgs("WindowBorderThickness"));
        }

    }

    public ICommand ButtonCommand { get { return new RelayCommand(delegate { TriggerPropertyChanges(); }); } }

    public int WindowWidth { get { return 100; } }
    public int WindowHeight { get { return 200; } }
    public int WindowBorderThickness { get { return 8; } }
}

现在,当我单击按钮时,会调用 WindowBorderThickness 的 getter,但不会调用 WindowWidth 和 WindowHeight 的 getter。这一切对我来说似乎很奇怪和不一致。我错过了什么?

【问题讨论】:

  • 调试时输出窗口有警告吗?

标签: c# .net wpf data-binding binding


【解决方案1】:

尝试使用两种方式绑定,它对我有用:

Width="{Binding Path=xExt, Mode=TwoWay}"

【讨论】:

    【解决方案2】:

    我将尝试回答我自己的问题。绑定正在工作,但我们不能确定布局系统是否要求例如窗口的 Width 属性。

    来自MSDN

    如果此元素是某个其他元素中的子元素,则将此属性设置为一个值实际上只是一个建议值。布局系统以及父元素的特定布局逻辑将在布局过程中将该值用作非绑定输入。实际上,FrameworkElement 几乎总是其他东西的子元素。即使您在窗口上设置了高度。 (对于 Window,当底层应用程序模型建立了创建承载应用程序的 Hwnd 的基本渲染假设时,将使用该值。)

    似乎可行的解决方案是将 WindowWidth 属性绑定到 MinWidth 和 MaxWidth 以及 Width。至少在我上面使用的测试场景中,将检索其中之一。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,我注意到这取决于在 xaml 中是先写高度还是宽度。如果高度是第一位的,那么 Binding 仅适用于它,反之亦然。解决方案是将绑定模式设置为“TwoWay”: 我所做的项目是使用 MS Studio 2010 和 .NET 4.0

      【讨论】:

        【解决方案4】:

        好的,

        我遇到了同样的问题,无法通过 XAML 将窗口尺寸(最小、最大、正常)正确绑定到我的视图模型。

        我不知道为什么,但是如果您通过代码而不是 XAML 进行绑定,那么您可以毫无问题地实现所有这些绑定。

        这是我的 C# 代码:

        this.SetBinding(Window.WidthProperty, new Binding("Width") { Source = MyViewModel, Mode=BindingMode.TwoWay });
        this.SetBinding(Window.HeightProperty, new Binding("Height") { Source = MyViewModel, Mode=BindingMode.TwoWay });
        this.SetBinding(Window.MaxWidthProperty, new Binding("MaxWidth") { Source = MyViewModel });
        this.SetBinding(Window.MaxHeightProperty, new Binding("MaxHeight") { Source = MyViewModel });
        this.SetBinding(Window.MinWidthProperty, new Binding("MinWidth") { Source = MyViewModel });
        this.SetBinding(Window.MinHeightProperty, new Binding("MinHeight") { Source = MyViewModel });
        

        奇怪的是它只适用于代码而不适用于 XAML。更奇怪的是,它默认为 mmin 和 Max 尺寸绑定 TwoWay,但不为您必须指定 «Mode=BindingMode.TwoWay » 的 Normal 尺寸绑定。

        应该有一个错误,微软必须对此进行纠正......

        【讨论】:

        • 这里也一样。在 XAML 中不起作用,但在代码中。在我的情况下,绑定到 WidthHeight 就足够了。
        【解决方案5】:

        此外,您可以将SizeToContent="WidthAndHeight"MinHeightMinWidth 一起使用,因此MaxHeightMaxWidth 不需要额外调用。

        【讨论】:

          【解决方案6】:

          绑定到 MinWidth 和 MinHeight 是正确的。此外,如果您需要绑定到 MaxWidth 和 MaxHeight,如果您的动态会放大或缩小 Window 的大小。

          【讨论】:

            【解决方案7】:

            我已使用以下代码解决了此问题。我希望它可以帮助某人。

            要点: WPF 中的动态绑定始终只适用于属性,而不适用于变量。

            在 .xaml.cs 文件中声明一个全局公共属性,如下所示:

            public Double DynamicHeight { get; set; }
            
            // Set DynamicHeight property value in Window_Loaded or any other event
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                 DynamicHeight = 200;
            }
            

            在 .xaml 文件中设置动态高度,如下所示:

            <Grid Height="{Binding DynamicHeight, Mode=TwoWay}">
            </Grid>
            

            如果您觉得这个答案有用,请投票给它。谢谢!

            【讨论】:

              【解决方案8】:

              我不确定您的具体实现,但我只是写一个可能有用的示例。

              XAML

              <Window x:Name="MainWindow"
                  x:Class="MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  Title="MainWindow" 
                  MinWidth="200"
                  MinHeight="100"
                  Width="{Binding ElementName=MainWindow, Path=WindowWidth}"
                  Height="{Binding ElementName=MainWindow, Path=WindowHeight}">
                  <Grid>
                      <Slider 
                          x:Name="slWidth" 
                          Value="{Binding ElementName=MainWindow, Path=WindowWidth, Mode=TwoWay}"
                          Minimum="200"
                          Maximum="1600"
                          Height="23" HorizontalAlignment="Left" Margin="56,22,0,0" VerticalAlignment="Top" Width="61" />
                      <Label 
                          Content="Width" 
                          Height="28" 
                          HorizontalAlignment="Left" 
                          Margin="12,22,0,0" 
                          Name="Label1" 
                          VerticalAlignment="Top" />
                      <Slider 
                          x:Name="slHeight" 
                          Value="{Binding ElementName=MainWindow, Path=WindowHeight, Mode=TwoWay}"
                          Minimum="100"
                          Maximum="800"
                          Height="23" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="61" Margin="56,51,0,0" />
                      <Label 
                          Content="Height" 
                          Height="28" 
                          HorizontalAlignment="Left"              
                          VerticalAlignment="Top" Margin="12,46,0,0" />
                  </Grid>
              </Window>
              

              代码

              Class MainWindow
              
                  Public Shared ReadOnly WindowWidthProperty As DependencyProperty = _
                                         DependencyProperty.Register("WindowWidth", _
                                         GetType(Integer), GetType(MainWindow), _
                                         New FrameworkPropertyMetadata(Nothing))
              
                  Public Shared ReadOnly WindowHeightProperty As DependencyProperty = _
                                       DependencyProperty.Register("WindowHeight", _
                                       GetType(Integer), GetType(MainWindow), _
                                       New FrameworkPropertyMetadata(Nothing))
              
                  Public Property WindowWidth As Integer
                      Get
                          Return CInt(GetValue(WindowWidthProperty))
                      End Get
                      Set(ByVal value As Integer)
                          SetValue(WindowWidthProperty, value)
                      End Set
                  End Property
              
                  Public Property WindowHeight As Integer
                      Get
                          Return CInt(GetValue(WindowHeightProperty))
                      End Get
                      Set(ByVal value As Integer)
                          SetValue(WindowHeightProperty, value)
                      End Set
                  End Property
              
              
              End Class
              

              C#代码

              public readonly DependencyProperty WindowWidthProperty = DependencyProperty.Register("WindowWidth", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());
              public readonly DependencyProperty WindowHeightProperty = DependencyProperty.Register("WindowHeight", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());
              
              public double WindowWidth {
                  get { return Convert.ToDouble(this.GetValue(WindowWidthProperty)); }
                  set { this.SetValue(WindowWidthProperty, value); }
              }
              
              public double WindowHeight {
                  get { return Convert.ToDouble(this.GetValue(WindowHeightProperty)); }
                  set { this.SetValue(WindowHeightProperty, value); }
              }
              

              【讨论】:

              • 这里的基本区别是您绑定到 MainWindow 本身,而我绑定到单独的视图模型。出于某种原因,这似乎有所作为。如果我针对我的视图模型实现您的滑块,它将不起作用(除非我也绑定到 MinHeight 和 MaxHeight ,就像我在自己的回答中所说的那样)。无论如何,谢谢你的例子。
              【解决方案9】:
              Height="{DynamicResource {x:Static SystemParameters.PrimaryScreenHeightKey}}" Width="{DynamicResource {x:Static SystemParameters.PrimaryScreenWidthKey}}"
              

              我的工作正常。

              【讨论】:

                【解决方案10】:

                只需添加 Mode = TwoWay Width="{Binding WindowWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, FallbackValue=350}"

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-06-05
                  • 1970-01-01
                  • 2011-10-20
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-09-09
                  • 1970-01-01
                  • 2012-09-02
                  相关资源
                  最近更新 更多