Wpf 基于子属性设置窗体最小宽度和最小高度
我正在使用MVVM模式在WPF中编写一个应用程序。在我的应用程序中,我有一个Wpf 基于子属性设置窗体最小宽度和最小高度,wpf,mvvm,Wpf,Mvvm,我正在使用MVVM模式在WPF中编写一个应用程序。在我的应用程序中,我有一个ipoppupWindowsService,我用它创建一个弹出对话框窗口 因此,要在弹出窗口中显示ViewModel,您可以执行以下操作: var container = ServiceLocator.Current.GetInstance<IUnityContainer>(); var popupService = container.Resolve<IPopupWindowService>()
ipoppupWindowsService
,我用它创建一个弹出对话框窗口
因此,要在弹出窗口中显示ViewModel,您可以执行以下操作:
var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
var popupService = container.Resolve<IPopupWindowService>();
var myViewModel = container.Resolve<IMyViewModel>();
popupService.Show((ViewModelBase)myViewModel);
<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>
我的弹出视图如下所示:
var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
var popupService = container.Resolve<IPopupWindowService>();
var myViewModel = container.Resolve<IMyViewModel>();
popupService.Show((ViewModelBase)myViewModel);
<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>
好啊
取消
您可以在ViewModel上定义
MinHeight
和MinWidth
属性,并使用数据绑定将视图绑定到XAML中的这些属性:
<...
MinHeight="{Binding Path=MinHeight}"
MinWidth="{Binding Path=MinWidth}"
.../>
您可以在ViewModel上定义
MinHeight
和MinWidth
属性,并使用数据绑定将视图绑定到XAML中的这些属性:
<...
MinHeight="{Binding Path=MinHeight}"
MinWidth="{Binding Path=MinWidth}"
.../>
我设计了完全相同的通用模式对话框控件(使用针对类型的数据模板),也遇到了这个问题
- 使用RelativeSource不起作用,因为您只能通过这种方式找到祖先(afaik)
- 另一种可能的解决方案是命名ContentPresenter,并使用ElementName绑定绑定到其上的属性。但是,ContentPresenter不会从其呈现的可视子级“继承”MinHeight和MinWidth属性
DependencyObject lObj = VisualTreeHelper.GetChild(this.WindowContent, 0);
if (lObj != null && lObj is FrameworkElement)
{
lWindowContentMinHeight = ((FrameworkElement)lObj).MinHeight;
lWindowContentMinWidth = ((FrameworkElement)lObj).MinWidth;
}
我将这段代码放在ModalDialogView的代码背后的OnActivated()覆盖中(在OnInitialized中,视图还不能被解析)
唯一剩下的问题是修正这些最小值,以便将窗口宽度和按钮面板高度考虑在内
更新
下面是我在通用模态对话框中使用的代码。它解决了以下附加问题:
- 它正确地以所有者窗口为中心
- 如果内容未设置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; } }
- 使用RelativeSource不起作用,因为您只能通过这种方式找到祖先(afaik)
- 另一种可能的解决方案是命名ContentPresenter,并使用ElementName绑定绑定到其上的属性。但是,ContentPresenter不会从其呈现的可视子级“继承”MinHeight和MinWidth属性
DependencyObject lObj = VisualTreeHelper.GetChild(this.WindowContent, 0);
if (lObj != null && lObj is FrameworkElement)
{
lWindowContentMinHeight = ((FrameworkElement)lObj).MinHeight;
lWindowContentMinWidth = ((FrameworkElement)lObj).MinWidth;
}
我将这段代码放在ModalDialogView的代码背后的OnActivated()覆盖中(在OnInitialized中,视图还不能被解析)
唯一剩下的问题是修正这些最小值,以便将窗口宽度和按钮面板高度考虑在内
更新
下面是我在通用模态对话框中使用的代码。它解决了以下附加问题:
- 它正确地以所有者窗口为中心
- 如果内容未设置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; } }