我一直在开发一个用于 ISO 集成的小工具,我决定将 WPF 用于 UI。我也在尽我所能在未来的项目中遵循 MVVM 模式。对于主窗口,我决定使用 WindowChrome,这样我就可以使用重新设置样式的窗口继续调整大小,但是,当我尝试选择不同的视图时,它会导致异常。我对其进行了测试,它确实可以正常工作,但是一旦我尝试将内容绑定到模板内容,它似乎会导致更改当前视图出现问题。
主窗口 xaml:
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="{Binding ResizeBorderThickness}"
CaptionHeight="{Binding TitleHeight}" GlassFrameThickness="0"/>
</WindowChrome.WindowChrome>
<Window.Resources>
<Style TargetType="{x:Type local:OSToolWPF}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Padding="{Binding OuterMarginThickness}">
<Grid>
<Border CornerRadius="{Binding WindowCornerRadius}"
Background="{StaticResource BackgroundLightBrush}">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Opacity=".2"/>
</Border.Effect>
</Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding TitleHeightGridLength, FallbackValue=50}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border CornerRadius="10 10 0 0"
Background="{StaticResource BackgroundDarkBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Viewbox Margin="25 0 0 0" HorizontalAlignment="Left">
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Title}"/>
</Viewbox>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button Style="{StaticResource ButtonBase}" Command="{Binding Minimize}" Width="50">
<Image Style="{StaticResource ControlImage}" Source="/Assets/Top/Minimize.png" Stretch="None"/>
</Button>
<Button Style="{StaticResource ButtonBase}" Command="{Binding Maximize}" Width="50">
<Image Style="{StaticResource ControlImage}" Source="/Assets/Top/Windowed.png" Stretch="None"/>
</Button>
<Button Style="{StaticResource ButtonBase}" Command="{Binding Close}" Width="50">
<Image Style="{StaticResource ControlImage}" Source="/Assets/Top/Close.png" Stretch="None"/>
</Button>
</StackPanel>
</Grid>
</Border>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel>
<Button Style="{StaticResource ButtonBase}" Tag="Registry" Command="{Binding Menu}"
Content="Registry" FontSize="20" Height="50" CommandParameter="{Binding
RelativeSource={RelativeSource Mode=Self}, Path=Tag}"/>
<Button Style="{StaticResource ButtonBase}" Tag="Services" Command="{Binding Menu}"
Content="Services" FontSize="20" Height="50" CommandParameter="{Binding
RelativeSource={RelativeSource Mode=Self}, Path=Tag}"/>
<Button Style="{StaticResource ButtonBase}" Tag="Visuals" Command="{Binding Menu}"
Content="Visuals" FontSize="20" Height="50" CommandParameter="{Binding
RelativeSource={RelativeSource Mode=Self}, Path=Tag}"/>
</StackPanel>
<Button Grid.Row="2" Style="{StaticResource ButtonBase}"
Content="Exit" FontSize="20" Command="{Binding Close}"
Height="50"/>
</Grid>
<Border Grid.Column="1">
<ContentControl Content="{TemplateBinding Content}"/>
<Border/>
</Grid>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<ContentControl Content="{Binding CurrentView}"/>
主窗口视图模型(数据绑定在 xaml.cs 中完成,因为它需要一个窗口):
public class OSToolViewModel : BaseViewModel
{
#region Private
private Window wWindow;
private object wCurrentView;
private int wOuterMarginSize = 10;
private int wWindowRadius = 15;
#endregion
public OSToolViewModel(Window window)
{
wWindow = window;
wWindow.StateChanged += (sender, e) =>
{
OnPropertyChanged(nameof(ResizeBorderThickness));
OnPropertyChanged(nameof(OuterMarginSize));
OnPropertyChanged(nameof(OuterMarginThickness));
OnPropertyChanged(nameof(WindowRadius));
OnPropertyChanged(nameof(WindowCornerRadius));
};
Menu = new BaseCommand(e => CurrentView = new ExpanderItemsList());
Minimize = new BaseCommand(e => wWindow.WindowState = WindowState.Minimized);
Maximize = new BaseCommand(e => wWindow.WindowState ^= WindowState.Maximized);
Close = new BaseCommand(e => CloseMessage());
}
#region Voids
private void CloseMessage()
{
if (DialogBox.Show("Would you like to exit?", "", wWindow.Title, DialogBoxButtons.YesNo) == DialogResult.Yes)
{
wWindow.Close();
}
}
#endregion
#region Commands
public BaseCommand Menu { get; set; }
public BaseCommand Minimize { get; set; }
public BaseCommand Maximize { get; set; }
public BaseCommand Close { get; set; }
#endregion
#region Public
public object CurrentView
{
get { return wCurrentView; }
set
{
if (value == wCurrentView)
return;
wCurrentView = value;
OnPropertyChanged(nameof(CurrentView));
}
}
public int ResizeBorder { get; set; } = 6;
public int OuterMarginSize
{
get
{
return wWindow.WindowState == WindowState.Maximized ? 0 : wOuterMarginSize;
}
set
{
wOuterMarginSize = value;
}
}
public int WindowRadius
{
get
{
return wWindow.WindowState == WindowState.Maximized ? 0 : wWindowRadius;
}
set
{
wWindowRadius = value;
}
}
public double TitleHeight { get; set; } = 50;
public Thickness ResizeBorderThickness { get { return new Thickness(ResizeBorder + OuterMarginSize); } }
public Thickness OuterMarginThickness { get { return new Thickness(OuterMarginSize); } }
public CornerRadius WindowCornerRadius { get { return new CornerRadius(WindowRadius); } }
public GridLength TitleHeightGridLength { get { return new GridLength(TitleHeight + ResizeBorder); } }
#endregion
}
我试图绑定的视图是一个页面,所以我不确定这是否会导致问题,但我尝试了很多不同的组合,我共享的组合导致异常。如果我没有绑定到模板内容,它会正常工作。我对为什么会发生这种情况感到困惑,并且作为旁注,窗口中的按钮并没有像它们应该的那样弯曲,所以如果你也有解决方案,那将不胜感激!谢谢你,我希望你过得愉快!