绑定到窗口高度和宽度的问题

D.H*_*.H. 24 .net c# data-binding wpf binding

当我尝试将窗口的高度和宽度绑定到视图模型中的属性时,我遇到了一些问题.这是一个小样本应用程序来说明问题.这是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

这是视图模型:

public class MainWindowViewModel
{
    public int WindowWidth { get { return 100; } }
    public int WindowHeight { get { return 200; } }
    public int WindowBorderThickness { get { return 8; } }
}
Run Code Online (Sandbox Code Playgroud)

程序启动时,会调用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; } }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我单击按钮时,将调用WindowBorderThickness的getter,但不会调用WindowWidth和WindowHeight的getter.这一切看起来都非常奇怪而且与我不一致.我错过了什么?

Gre*_*ont 41

尝试使用双向绑定,它对我有用:

Width="{Binding Path=xExt, Mode=TwoWay}"
Run Code Online (Sandbox Code Playgroud)


D.H*_*.H. 10

我会尽力回答我自己的问题.绑定工作正常,但我们无法确定布局系统是否要求例如窗口的Width属性.

来自MSDN:

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

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


VNe*_*kov 10

我有同样的问题,我注意到它取决于是否首先在xaml中写入高度或宽度.如果高度是第一个,那么Binding只为它工作,反之亦然.解决方案是将Binding模式设置为'TwoWay':我所做的项目是使用MS Studio 2010和.NET 4.0


小智 6

好的,

我遇到了同样的问题,无法通过 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 });
Run Code Online (Sandbox Code Playgroud)

奇怪的是它只适用于代码而不适用于 XAML。更奇怪的是,它默认为 mMin 和 Max 维度绑定了 TwoWay,但对于您必须指定 « Mode=BindingMode.TwoWay » 的 Normal 维度则不然。

应该有一个微软必须纠正的错误......


小智 5

此外,您可以使用SizeToContent="WidthAndHeight"MinHeightMinWidth,所以没有额外的调用需要的MaxHeightMaxWidth.