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 Locator}}">
<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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With