在 MVVM 中以编程方式更改 WPF 窗口大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18659111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:36:11  来源:igfitidea点击:

Change WPF window Size programmatically in MVVM

c#wpfmvvm

提问by user2519971

How do you change the size of your Window in WPF programmatically using an MVVM approach?

如何使用 MVVM 方法以编程方式更改 WPF 中窗口的大小?

I am setting the window height to 400 from XAML and on click of a button on the form trying to increase the height to 500.

我正在将窗口高度从 XAML 设置为 400,然后单击表单上的按钮尝试将高度增加到 500。

In my button's ICommand I am using:

在我的按钮的 ICommand 中,我正在使用:

Application.Current.MainWindow.Height = 500;

But it's not doing anything.

但它什么也没做。

回答by Sheridan

Try setting the 'Application.Current.MainWindow' property in the Loadedevent in the MainWindow.xaml.csfile:

尝试LoadedMainWindow.xaml.cs文件中的事件中设置“Application.Current.MainWindow”属性:

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    Application.Current.MainWindow = this;
}

UPDATE >>>

更新 >>>

My friend, please remember, yousaid you wanted to use Application.Current.MainWindow... this is how you could use it. However, if you want to do this the MVVM way, then why don't you just bind the value to the Window.Widthproperties?

我的朋友,请记住,说你想使用Application.Current.MainWindow......这就是你可以使用它的方式。但是,如果您想以 MVVM 方式执行此操作,那么为什么不将值绑定到Window.Width属性呢?

<Window Width="{Binding Width}" MinWidth="{Binding Width}" MaxWidth="{Binding Width}">
    ...
</Window>

Please note that binding to Window.Widthis notenough for this to work.

请注意,结合Window.Width不是够这个工作。

回答by Jim Windram

I had a similar requirement to this, with the addition that I wanted to track some other window settings. So, I have this class:

我对此有类似的要求,另外我想跟踪一些其他窗口设置。所以,我有这门课:

public class WindowSettings
{
    public int Width { get; set; }

    public int Height { get; set; }

    public int Left { get; set; }

    public int Top { get; set; }
}

Then in my view model, I have:

然后在我的视图模型中,我有:

public WindowSettings WindowSettings
{
    get
    {
        return _windowSettings;
    }
}

and in the xaml, this:

在 xaml 中,这个:

<Window ...
    Height="{Binding WindowSettings.Height,Mode=TwoWay}"
    Width="{Binding WindowSettings.Width, Mode=TwoWay}"
Left="{Binding WindowSettings.Left,Mode=TwoWay}"
    Top="{Binding WindowSettings.Top,Mode=TwoWay}">

If I wanted to programmatically update the width, for example, I do this:

例如,如果我想以编程方式更新宽度,我会这样做:

WindowSettings.Width = 456;
RaisePropertyChangedEvent("WindowSettings.Width");

(Naturally, my view model inherits from a base class which implements INotifyPropertyChanged.)

(当然,我的视图模型继承自实现 INotifyPropertyChanged 的​​基类。)

I did toy with the idea of providing an event on the WindowSettings class so that an update to a property could automatically cause the property change notification, but my requirement is to track the window size and set it on startup, so I didn't bother. Hope that helps.

我想在 WindowSettings 类上提供一个事件,以便对属性的更新可以自动导致属性更改通知,但我的要求是跟踪窗口大小并在启动时设置它,所以我没有打扰. 希望有帮助。

回答by Jym

Using VS 2017 and Caliburn Micro I have no issue with just setting the width. The way you are doing it isn't MVVM your VM doesn't need to know about the V or what's happening when the int Width changes.

使用 VS 2017 和 Caliburn Micro 我只设置宽度没有问题。您这样做的方式不是 MVVM,您的 VM 不需要知道 V 或 int Width 更改时发生的情况。

public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
{
    public ShellViewModel()
    {
        Width = 500;
    }
    private int _width;
    public int Width
    {
        get => _width;
        set
        {
            _width = value;
            NotifyOfPropertyChange(() => Width);
        }
    }
    public void MyButton()
    {
        Width = 800;
    }

}

In the Window XAML

在窗口 XAML 中

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

In the Grid

在网格中

<Button x:Name="MyButton" Content="Make 800 wide" />

it opens at 500 and when I click the button it stretches to 800.

它以 500 开盘,当我单击按钮时,它会拉伸到 800。

回答by Neil B

I'm adding this answer because the most voted answer actually isn't correct. Binding to the MinHeight & MaxHeight, will result in a window that can't be resized using the grips.

我添加这个答案是因为投票最多的答案实际上是不正确的。绑定到 MinHeight 和 MaxHeight,将导致无法使用夹点调整大小的窗口。

<Window Width="{Binding Width}" MinWidth="{Binding Width}" MaxWidth="{Binding Width}">
    ...
</Window>

Instead add Mode=TwoWayto your binding.

而是添加Mode=TwoWay到您的绑定中。

<Window Width="{Binging Width, Mode=TwoWay}">
    ...
</Window>

回答by Maple Wan

Are you sure the window you want to resize is MainWindow? Or are you sure your command is successfully binding on your button? You can try the below code:

您确定要调整大小的窗口是 MainWindow 吗?或者您确定您的命令已成功绑定到您的按钮上?你可以试试下面的代码:

View:

看法:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication1.ViewModel"
        Title="Wpf Application" Height="300" Width="400"
        WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <viewModel:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <Button Content="Resize" Command="{Binding ResizeCommand}" IsEnabled="{Binding ResizeCommand.CanExecute}" />
    </Grid>
</Window>

ViewModel:

视图模型:

public class MainWindowViewModel
{
    private RelayCommand _resizeCommand;

    public RelayCommand ResizeCommand { get { return _resizeCommand; } }

    public MainWindowViewModel()
    {
        this._resizeCommand = new RelayCommand(this.Resize);
    }

    private void Resize()
    {
        Application.Current.MainWindow.Height = 500;
    }
}