开发者

Getting Window Properties in ViewModel

开发者 https://www.devze.com 2023-04-10 10:26 出处:网络
I\'m building a WPF application in which I have a need to get the width, height and locations of the window from my view model. I\'m using the following XAML:

I'm building a WPF application in which I have a need to get the width, height and locations of the window from my view model. I'm using the following XAML:

<Window x:Class="ScreenCapture.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"
        mc:Ignorable="d"
        Height="{Binding Height, Mode=OneWayToSource, FallbackValue=300}"
        Width="{Binding Width, Mode=OneWayToSource, FallbackValue=300}"
        Title="MVVM Light Application"
        Top="{Binding Top, Mode=OneWayToSource}"
        Left="{Binding Left, Mode=OneWayToSource}"
        DataContext="{Binding Main, Source={StaticResource Lo开发者_开发技巧cator}}">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="13*" />
            <ColumnDefinition Width="265*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="25" />
        </Grid.RowDefinitions>
        <TextBlock FontSize="36"
                   FontWeight="Bold"
                   Foreground="Purple"
                   Text="{Binding Welcome}"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   TextWrapping="Wrap" Grid.Column="1" Margin="19,70,32,70" />
        <Button Grid.Row="1" Content="Capture" Grid.ColumnSpan="2" Command="{Binding Capture}" />
    </Grid>
</Window>

In my view model, the values for the Top, Left work fine, but, the Width and Height properties are both NaN. I have properties like this for each of the attributes I'm binding on:

private double height;

public double Height
{
    set
    {
        height = value;
    }
}

Any idea why the values are coming back NaN? More importantly, what can I do to get the values I'm looking for?

EDIT: I realize this is a bit off, but I need to capture a screenshot of the application from the view model. The view model contains additional properties that I didn't paste, but are necessary in order to implement the desired functionality. For the curious, below is my method for capturing the screen:

private void CaptureScreen()
{
    int x = Convert.ToInt32(left);
    int y = Convert.ToInt32(top);
    int w = Convert.ToInt32(width);
    int h = Convert.ToInt32(height);
    Bitmap image = new Bitmap(w, h);
    Graphics graphics = Graphics.FromImage(image);

    graphics.CopyFromScreen(x, y, x, y, new Size(w, h), CopyPixelOperation.SourceCopy);

    // Do something with the image
}


As mzabsky said, you need to use ActualWidth and ActualHeight. The problem here is that they are readonly and you can't do a OneWayToSource Binding on a readonly Dependency Property.

However, there are workarounds.
See the following question: Pushing read-only GUI properties back into ViewModel

The attached behavior provided by Kent Boogaart lets you do this

<Window ...
        SizeObserver.Observe="True"
        SizeObserver.ObservedWidth="{Binding Width, Mode=OneWayToSource}"
        SizeObserver.ObservedHeight="{Binding Height, Mode=OneWayToSource}">

or you can try the solution I made for this called PushBinding which can be used to push readonly DP's to the viewmodel. In your case the usage would look like this

<Window ...>
    <pb:PushBindingManager.PushBindings> 
        <pb:PushBinding TargetProperty="ActualHeight" Path="Height"/> 
        <pb:PushBinding TargetProperty="ActualWidth" Path="Width"/>
    </pb:PushBindingManager.PushBindings> 
</Window> 

You can download a demo project using PushBinding here if you're interested: https://www.dropbox.com/s/eqkmsp0q7hb568z/PushBindingInStyleDemo.zip?dl=0


You are supposed to use ActualWidth and ActualHeight as binding targets for one way to source binding, not Height and Width - those are desired size, not actual size. Width and Height is NaN unless you specifically set them to some value.

Of course, another question is that this doesn't seem like proper use of view model.

0

精彩评论

暂无评论...
验证码 换一张
取 消