Проблемы с привязкой к Высоте Окна и Ширине

У меня есть некоторые проблемы, когда я пытаюсь связать высоту и ширину окна к свойствам, по моему мнению, модель. Вот приложение небольшой выборки для иллюстрирования проблемы. Это - код в 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();
    }
}

Это - 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>

И это - модель представления:

public class MainWindowViewModel
{
    public int WindowWidth { get { return 100; } }
    public int WindowHeight { get { return 200; } }
    public int WindowBorderThickness { get { return 8; } }
}

Когда программа запущена, методы считывания WindowHeight и WindowBorderThickness (но не WindowWidth) называют, таким образом, высота и граница окна установлены правильно, но не ширина.

Я затем добавляю кнопку, которая инициирует 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; } }
}

Теперь, когда я нажимаю кнопку, метод считывания WindowBorderThickness называют, но не те для WindowWidth и WindowHeight. Все это просто кажется очень странным и непоследовательным мне. Что я пропускаю?

24
задан D.H. 20 April 2010 в 10:49
поделиться

2 ответа

Я постараюсь ответить на свой вопрос. Привязки работают, но мы не можем быть уверены, что система макета запрашивает, например, свойство Ширина окна.

Из MSDN :

Если этот элемент является дочерним элементом в каком-либо другом элементе, то установка этого свойства в значение на самом деле является только рекомендуемым значением. Система макета, а также конкретная логика макета родительского элемента будут использовать значение в качестве необязательного ввода во время процесса макета. На практике FrameworkElement почти всегда является дочерним элементом чего-то еще; даже когда вы устанавливаете высоту окна. (Для Window это значение используется, когда базовая модель приложения устанавливает базовые предположения о рендеринге, которые создают Hwnd, на котором размещается приложение.)

Решение, которое, похоже, работает, - это привязать свойство WindowWidth к MinWidth и MaxWidth, а также как ширина. Один из них будет получен, по крайней мере, в тестовом сценарии, который я использовал выше.

10
ответ дан 28 November 2019 в 22:29
поделиться

Я не уверен насчет вашей конкретной реализации, но я просто пишу пример, который может оказаться полезным.

XAML

<Window x:Name="MainWindow"
    x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" 
    MinWidth="200"
    MinHeight="100"
    Width="{Binding ElementName=MainWindow, Path=WindowWidth}"
    Height="{Binding ElementName=MainWindow, Path=WindowHeight}">
    <Grid>
        <Slider 
            x:Name="slWidth" 
            Value="{Binding ElementName=MainWindow, Path=WindowWidth, Mode=TwoWay}"
            Minimum="200"
            Maximum="1600"
            Height="23" HorizontalAlignment="Left" Margin="56,22,0,0" VerticalAlignment="Top" Width="61" />
        <Label 
            Content="Width" 
            Height="28" 
            HorizontalAlignment="Left" 
            Margin="12,22,0,0" 
            Name="Label1" 
            VerticalAlignment="Top" />
        <Slider 
            x:Name="slHeight" 
            Value="{Binding ElementName=MainWindow, Path=WindowHeight, Mode=TwoWay}"
            Minimum="100"
            Maximum="800"
            Height="23" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="61" Margin="56,51,0,0" />
        <Label 
            Content="Height" 
            Height="28" 
            HorizontalAlignment="Left"              
            VerticalAlignment="Top" Margin="12,46,0,0" />
    </Grid>
</Window>

Код

Class MainWindow

    Public Shared ReadOnly WindowWidthProperty As DependencyProperty = _
                           DependencyProperty.Register("WindowWidth", _
                           GetType(Integer), GetType(MainWindow), _
                           New FrameworkPropertyMetadata(Nothing))

    Public Shared ReadOnly WindowHeightProperty As DependencyProperty = _
                         DependencyProperty.Register("WindowHeight", _
                         GetType(Integer), GetType(MainWindow), _
                         New FrameworkPropertyMetadata(Nothing))

    Public Property WindowWidth As Integer
        Get
            Return CInt(GetValue(WindowWidthProperty))
        End Get
        Set(ByVal value As Integer)
            SetValue(WindowWidthProperty, value)
        End Set
    End Property

    Public Property WindowHeight As Integer
        Get
            Return CInt(GetValue(WindowHeightProperty))
        End Get
        Set(ByVal value As Integer)
            SetValue(WindowHeightProperty, value)
        End Set
    End Property


End Class

Код C #

public readonly DependencyProperty WindowWidthProperty = DependencyProperty.Register("WindowWidth", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());
public readonly DependencyProperty WindowHeightProperty = DependencyProperty.Register("WindowHeight", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());

public double WindowWidth {
    get { return Convert.ToDouble(this.GetValue(WindowWidthProperty)); }
    set { this.SetValue(WindowWidthProperty, value); }
}

public double WindowHeight {
    get { return Convert.ToDouble(this.GetValue(WindowHeightProperty)); }
    set { this.SetValue(WindowHeightProperty, value); }
}
0
ответ дан 28 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: