Получение свойств окна в ViewModel - PullRequest
8 голосов
/ 05 октября 2011

Я создаю приложение WPF, в котором мне нужно получить ширину, высоту и расположение окна из моей модели вида. Я использую следующий 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>

В моей модели представления, значения для Top, Left работают нормально, но свойства Width и Height оба NaN. У меня есть такие свойства для каждого из атрибутов, с которыми я связываюсь:

private double height;

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

Есть идеи, почему значения возвращаются NaN? Что еще более важно, что я могу сделать, чтобы получить значения, которые я ищу?

РЕДАКТИРОВАТЬ: Я понимаю, что это немного не так, но мне нужно сделать снимок экрана приложения из модели представления. Модель представления содержит дополнительные свойства, которые я не вставил, но они необходимы для реализации желаемой функциональности. Для любопытных ниже мой метод захвата экрана:

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
}

Ответы [ 2 ]

10 голосов
/ 05 октября 2011

Как сказал mzabsky , вам нужно использовать ActualWidth и ActualHeight.Проблема здесь в том, что они доступны только для чтения, и вы не можете выполнить OneWayToSource Binding для свойства зависимости только для чтения.

Однако есть обходные пути.
См. Следующий вопрос: Перенос свойств графического интерфейса только для чтения обратно во ViewModel

Прикрепленное поведение, предоставляемое Кент Бугаарт , позволяет вам сделать это

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

или вы можете попробовать решениеЯ сделал для этого PushBinding, который можно использовать для передачи DP только для чтения к модели представления.В вашем случае использование будет выглядеть так:

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

Вы можете скачать демонстрационный проект, используя PushBinding здесь, если вам интересно: https://www.dropbox.com/s/eqkmsp0q7hb568z/PushBindingInStyleDemo.zip?dl=0

2 голосов
/ 05 октября 2011

Вы должны использовать ActualWidth и ActualHeight в качестве целей привязки для одного способа привязки к источнику, а не высоты и ширины - это желаемый размер, а не фактический размер. Ширина и высота - это NaN, если вы не установили для них какое-либо значение.

Конечно, другой вопрос заключается в том, что это не похоже на правильное использование модели представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...