Установите форму MinWidth и MinHeight на основе дочернего свойства - PullRequest
1 голос
/ 26 февраля 2010

Я пишу приложение в WPF, используя шаблон MVVM.В моем приложении у меня есть IPopupWindowService, который я использую для создания всплывающего диалогового окна.

Таким образом, чтобы показать ViewModel во всплывающем окне, вы должны сделать что-то вроде этого:

var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
var popupService = container.Resolve<IPopupWindowService>();
var myViewModel = container.Resolve<IMyViewModel>();
popupService.Show((ViewModelBase)myViewModel);

Это все хорошо.Что я хочу сделать, так это иметь возможность установить MinHeight и MinWidth для View, привязанного к myViewModel, и заставить всплывающее окно использовать эти настройки, чтобы пользователь не мог сделать окно меньше, чем позволяет его содержимое.,В тот момент, когда пользователь сжимает окно, его содержимое перестает меняться, но окно не изменяется.

РЕДАКТИРОВАТЬ:

Я сопоставляю свои виды с моими ViewModels в ResourceDictionarys какитак:

<DataTemplate DataType="{x:Type ViewModels:MyViewModel}">
     <Views:MyView />
</DataTemplate>

А мой всплывающий вид выглядит так:

<Window x:Class="TheCompany.Cubit.Shell.Views.PopupWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        SizeToContent="WidthAndHeight"
        WindowStartupLocation="CenterOwner">
<DockPanel x:Name="panelContent">
    <StackPanel HorizontalAlignment="Right" DockPanel.Dock="Bottom" Orientation="Horizontal" Visibility="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=ButtonPanelVisibility}">
        <Button Width="75" IsDefault="True" x:Uid="ViewDialog_AcceptButton" Click="OnAcceptButtonClick" Margin="4">OK</Button>
        <Button Width="75" IsCancel="True" x:Uid="ViewDialog_CancelButton" Click="OnCancelButtonClick" Margin="0,4,4,4">Cancel</Button>
    </StackPanel>
    <ContentPresenter Content="{Binding}" />
</DockPanel>

Ответы [ 2 ]

3 голосов
/ 26 февраля 2010

Вы можете определить свойства MinHeight и MinWidth в ViewModel и использовать привязку данных для привязки View к этим свойствам в XAML:

<...
    MinHeight="{Binding Path=MinHeight}"
    MinWidth="{Binding Path=MinWidth}"
.../>
2 голосов
/ 27 мая 2010

Я разработал точно такой же универсальный модальный диалоговый элемент управления (используя DataTemplates с таргетингом на тип) и также наткнулся на эту проблему.

  • Использование RelativeSource не работает, потому что таким путем можно найти только предков (afaik).

  • Другим возможным решением было присвоить имя ContentPresenter и связать со свойствами этого объекта с помощью привязки ElementName. Однако ContentPresenter не «наследует» свойства MinHeight и MinWidth от визуального дочернего элемента, который он отображает.

Решением в конечном итоге стало использование VisualTreeHelper для получения разрешенного представления, связанного с ViewModel во время выполнения:

        DependencyObject lObj = VisualTreeHelper.GetChild(this.WindowContent, 0);
        if (lObj != null && lObj is FrameworkElement)
        {
            lWindowContentMinHeight = ((FrameworkElement)lObj).MinHeight;
            lWindowContentMinWidth = ((FrameworkElement)lObj).MinWidth;
        }

Я поместил этот код в переопределение OnActivation () в выделенном фрагменте кода ModalDialogView (в OnInitialized представление еще не может быть разрешено).

Единственная оставшаяся проблема заключается в исправлении этих минимумов так, чтобы учитывались ширина окна и высота панели кнопок.

UPDATE

Ниже приведен код, который я использую в моем модальном диалоговом окне. Это решает следующие дополнительные проблемы:

  • Правильно центрируется в окне владельца
  • Ничего не происходит, если для контента не установлены MinWidth и MinHeight

    private bool _MinSizeSet = false;
    
    public ModalDialogView(object pDataContext)
        : this()
    {
        this.DataContext = pDataContext;
        this.LayoutUpdated += new EventHandler(ModalDialogView_LayoutUpdated);
    }
    
    void ModalDialogView_LayoutUpdated(object sender, EventArgs e)
    {
        if (System.Windows.Media.VisualTreeHelper.GetChildrenCount(this.WindowContent) > 0)
            SetInitialAndMinimumSize();
    }
    
    private void SetInitialAndMinimumSize()
    {
        FrameworkElement lElement = VisualTreeHelper.GetChild(this.WindowContent, 0) as FrameworkElement;
        if (!_MinSizeSet && lElement != null)
        {
            if (lElement.MinWidth != 0 && lElement.MinHeight != 0)
            {
                double lHeightDiff = this.ActualHeight - this.WindowContent.ActualHeight;
                double lWidthDiff = this.ActualWidth - this.WindowContent.ActualWidth;
                this.MinHeight = lElement.MinHeight + lHeightDiff;
                this.MinWidth = lElement.MinWidth + lWidthDiff;
                this.SizeToContent = SizeToContent.Manual;
                this.Height = this.MinHeight;
                this.Width = this.MinWidth;
                this.Left = this.Owner.Left + (this.Owner.ActualWidth - this.ActualWidth) / 2;
                this.Top = this.Owner.Top + (this.Owner.ActualHeight - this.ActualHeight) / 2;
            }
            _MinSizeSet = true;
        }
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...