先上图
新建CustomControl,名:HeaderedWindow
ThemesGeneric.aml文件夹下加入
笔刷,转换器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <SolidColorBrush x:Key="ActiveBackground" Color="#FF66CBEA"/> 2 <SolidColorBrush x:Key="DeactiveBackground" Color="#FFC2D6DC"/> 3 <loc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
最大化,最小化,关闭按钮
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <Style x:Key="styleWindowButtonMinimize" TargetType="{x:Type Button}"> 2 <Setter Property="Template"> 3 <Setter.Value> 4 <ControlTemplate TargetType="{x:Type Button}"> 5 <Grid x:Name="buttonClose"> 6 <Border x:Name="btnEllipse" BorderThickness="1,0,1,1" BorderBrush="Black" Background="{TemplateBinding Background}"/> 7 <Path x:Name="iconMin" SnapsToDevicePixels="False" Height="21" Width="28" StrokeThickness="3" Stroke="Black" Fill="#FFFFFFFF" Data="M 8,13.5 L 19 13.5"/> 8 <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/> 9 </Grid> 10 <ControlTemplate.Triggers> 11 <Trigger Property="IsFocused" Value="True"/> 12 <Trigger Property="IsDefaulted" Value="True"/> 13 <Trigger Property="IsMouseOver" Value="True"> 14 <Setter Property="Background" Value="LightGreen" TargetName="btnEllipse"/> 15 </Trigger> 16 <Trigger Property="IsPressed" Value="True"/> 17 <Trigger Property="IsEnabled" Value="False"/> 18 </ControlTemplate.Triggers> 19 </ControlTemplate> 20 </Setter.Value> 21 </Setter> 22 </Style> 23 24 <Style x:Key="styleWindowButtonMaximize" TargetType="{x:Type ToggleButton}"> 25 <Setter Property="Template"> 26 <Setter.Value> 27 <ControlTemplate TargetType="{x:Type ToggleButton}"> 28 <Grid> 29 <Border x:Name="btnEllipse" Background="{TemplateBinding Background}" Width="25" Height="21" BorderBrush="Black" BorderThickness="0,0,0,1"/> 30 <Path x:Name="iconMax" SnapsToDevicePixels="False" Stroke="Black" StrokeThickness="2" Data="F1 M 9 7 H 18 V 14 H 9 V 7 H 18"/> 31 <Path x:Name="iconRestore" SnapsToDevicePixels="False" Visibility="Collapsed" Stroke="Black" StrokeThickness="1" Data="F1 M 10.5 5.5 H 17.5 V 12.5 M 8.5 7.5 H 15.5 V 14.5 H 8.5 V 7.5 H 9.5 V 13.5 H 14.5 V 8.5 H 8.5"/> 32 <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/> 33 </Grid> 34 <ControlTemplate.Triggers> 35 <Trigger Property="IsFocused" Value="True"/> 36 <Trigger Property="IsMouseOver" Value="True"> 37 <Setter Property="Background" Value="LightGreen" TargetName="btnEllipse"/> 38 </Trigger> 39 <Trigger Property="IsPressed" Value="True"/> 40 <Trigger Property="IsEnabled" Value="False"/> 41 <Trigger Property="IsChecked" Value="True"> 42 <Setter TargetName="iconMax" Property="Visibility" Value="Collapsed" /> 43 <Setter TargetName="iconRestore" Property="Visibility" Value="Visible" /> 44 </Trigger> 45 </ControlTemplate.Triggers> 46 </ControlTemplate> 47 </Setter.Value> 48 </Setter> 49 </Style> 50 51 <Style x:Key="styleMainWindowButtonClose" TargetType="{x:Type Button}"> 52 <Setter Property="Template"> 53 <Setter.Value> 54 <ControlTemplate TargetType="{x:Type Button}"> 55 <Grid x:Name="buttonClose" Width="47" Height="21"> 56 <Border x:Name="btnEllipse" BorderBrush="Black" BorderThickness="1,0,1,1" Background="{TemplateBinding Background}"/> 57 <Path x:Name="iconX" ClipToBounds="True" Stroke="Black" StrokeThickness="1" Data="F1 M 20 7 L 26 15 M 21 7 L 27 15 M 22 7 L 28 15 M 20 15 L 26 7 M 21 15 L 27 7 M 22 15 L 28 7"/> 58 <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/> 59 </Grid> 60 <ControlTemplate.Triggers> 61 <Trigger Property="IsFocused" Value="True"/> 62 <Trigger Property="IsDefaulted" Value="True"/> 63 <Trigger Property="IsMouseOver" Value="True"> 64 <Setter Property="Background" Value="#FFEC6C60" TargetName="btnEllipse"/> 65 </Trigger> 66 <Trigger Property="IsPressed" Value="True"/> 67 <Trigger Property="IsEnabled" Value="False"/> 68 </ControlTemplate.Triggers> 69 </ControlTemplate> 70 </Setter.Value> 71 </Setter> 72 </Style>
窗口样式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <Style TargetType="{x:Type loc:HeaderedWindow}"> 2 <Setter Property="WindowStyle" Value="None"/> 3 <Setter Property="ResizeMode" Value="NoResize"/> 4 <Setter Property="Background" Value="#FF66CBEA"/> 5 <Setter Property="BorderBrush" Value="Black"/> 6 <Setter Property="BorderThickness" Value="1"/> 7 <Setter Property="MinWidth" Value="90"/> 8 <Setter Property="MinHeight" Value="30"/> 9 <Setter Property="VerticalContentAlignment" Value="Stretch"/> 10 <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 11 <Setter Property="Template"> 12 <Setter.Value> 13 <ControlTemplate TargetType="{x:Type loc:HeaderedWindow}"> 14 <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> 15 <Grid SnapsToDevicePixels="True" Background="{TemplateBinding Background}"> 16 <Grid.RowDefinitions> 17 <RowDefinition x:Name="HeaderRow" Height="30" /> 18 <RowDefinition /> 19 </Grid.RowDefinitions> 20 <!-- Window header--> 21 <Grid Name="PART_HeaderContainer" Background="Transparent"> 22 <StackPanel Orientation="Horizontal" Margin="4,0" Visibility="{Binding RelativeSource={ x:Static RelativeSource.TemplatedParent}, Path=ShowDefaultHeader, Converter={ StaticResource BoolToVisibilityConverter }}"> 23 <Image Height="24" Width="24" HorizontalAlignment="Left" VerticalAlignment="Center" Source="{TemplateBinding Icon}"/> 24 <TextBlock Text="{TemplateBinding Title}" Margin="4,0" VerticalAlignment="Center" FontFamily="Arial" FontSize="15" Foreground="#FFFFFFFF" TextWrapping="NoWrap"/> 25 </StackPanel> 26 <StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Orientation="Horizontal" Margin="0,0,5,0"> 27 <Button x:Name="PART_MinimizeButton" IsTabStop="False" Style="{StaticResource styleWindowButtonMinimize}" Width="28" Height="21" ToolTip="Minimize" Visibility="{Binding RelativeSource={ x:Static RelativeSource.TemplatedParent}, Path=CanResize, Converter={ StaticResource BoolToVisibilityConverter }}"/> 28 <ToggleButton x:Name="PART_RestoreButton" IsTabStop="False" Style="{StaticResource styleWindowButtonMaximize}" Width="25" Height="21" ToolTip="Maximize" Visibility="{Binding RelativeSource={ x:Static RelativeSource.TemplatedParent}, Path=CanResize, Converter={ StaticResource BoolToVisibilityConverter }}"/> 29 <Button x:Name="PART_CloseButton" IsTabStop="False" Style="{StaticResource styleMainWindowButtonClose}" Width="47" Height="21" ToolTip="Close"/> 30 </StackPanel> 31 <ContentPresenter ContentSource="{TemplateBinding Header}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/> 32 </Grid> 33 <Grid Grid.RowSpan="2" x:Name="PART_ResizerContainers" Visibility="Hidden"> 34 <Grid.Resources> 35 <sys:Double x:Key="StraightResizerSize">4</sys:Double> 36 <sys:Double x:Key="SlantResizerSize">8</sys:Double> 37 <Style TargetType="{x:Type Thumb}"> 38 <Setter Property="Template"> 39 <Setter.Value> 40 <ControlTemplate> 41 <Rectangle Fill="Transparent"/> 42 </ControlTemplate> 43 </Setter.Value> 44 </Setter> 45 </Style> 46 </Grid.Resources> 47 <Thumb Width="{StaticResource StraightResizerSize}" VerticalAlignment="Stretch" HorizontalAlignment="Left" Cursor="SizeWE" x:Name="PART_LeftResizer"/> 48 <Thumb Height="{StaticResource StraightResizerSize}" VerticalAlignment="Top" HorizontalAlignment="Stretch" Cursor="SizeNS" x:Name="PART_TopResizer"/> 49 <Thumb Width="{StaticResource StraightResizerSize}" VerticalAlignment="Stretch" HorizontalAlignment="Right" Cursor="SizeWE" x:Name="PART_RightResizer"/> 50 <Thumb Height="{StaticResource StraightResizerSize}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Cursor="SizeNS" x:Name="PART_BottomResizer"/> 51 <ResizeGrip Width="{StaticResource SlantResizerSize}" Height="{StaticResource SlantResizerSize}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="{Binding RelativeSource={ x:Static RelativeSource.TemplatedParent}, Path=ShowResizeGrip, Converter={ StaticResource BoolToVisibilityConverter }}"/> 52 <Thumb Width="{StaticResource SlantResizerSize}" Height="{StaticResource SlantResizerSize}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE" x:Name="PART_BottomRightResizer"/> 53 <Thumb Width="{StaticResource SlantResizerSize}" Height="{StaticResource SlantResizerSize}" HorizontalAlignment="Right" VerticalAlignment="Top" Cursor="SizeNESW" x:Name="PART_TopRightResizer"/> 54 <Thumb Width="{StaticResource SlantResizerSize}" Height="{StaticResource SlantResizerSize}" HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE" x:Name="PART_TopLeftResizer"/> 55 <Thumb Width="{StaticResource SlantResizerSize}" Height="{StaticResource SlantResizerSize}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW" x:Name="PART_BottomLeftResizer"/> 56 </Grid> 57 <Border x:Name="PART_ContentBorder" Grid.Row="1" Margin="7,0,7,7" ClipToBounds="True" Background="White"> 58 <AdornerDecorator> 59 <ContentPresenter Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> 60 </AdornerDecorator> 61 </Border> 62 </Grid> 63 </Border> 64 <ControlTemplate.Triggers> 65 <MultiTrigger> 66 <MultiTrigger.Conditions> 67 <Condition Property="CanResize" Value="True"/> 68 <Condition Property="WindowState" Value="Normal"/> 69 </MultiTrigger.Conditions> 70 <Setter TargetName="PART_ResizerContainers" Property="Visibility" Value="Visible"/> 71 </MultiTrigger> 72 <Trigger Property="WindowState" Value="Maximized"> 73 <Setter TargetName="PART_ContentBorder" Property="Margin" Value="0"/> 74 <Setter TargetName="PART_ContentBorder" Property="BorderThickness" Value="0,2,0,0"/> 75 <Setter TargetName="HeaderRow" Property="Height" Value="25"/> 76 </Trigger> 77 <Trigger Property="IsActive" Value="False"> 78 <Setter Property="Background" Value="{StaticResource DeactiveBackground}"/> 79 <Setter TargetName="PART_MinimizeButton" Property="Background" Value="{StaticResource DeactiveBackground}"/> 80 <Setter TargetName="PART_RestoreButton" Property="Background" Value="{StaticResource DeactiveBackground}"/> 81 <Setter TargetName="PART_CloseButton" Property="Background" Value="{StaticResource DeactiveBackground}"/> 82 </Trigger> 83 <Trigger Property="IsActive" Value="True"> 84 <Setter Property="Background" Value="{StaticResource ActiveBackground}"/> 85 <Setter TargetName="PART_MinimizeButton" Property="Background" Value="{StaticResource ActiveBackground}"/> 86 <Setter TargetName="PART_RestoreButton" Property="Background" Value="{StaticResource ActiveBackground}"/> 87 <Setter TargetName="PART_CloseButton" Property="Background" Value="#FFC35A50"/> 88 </Trigger> 89 </ControlTemplate.Triggers> 90 </ControlTemplate> 91 </Setter.Value> 92 </Setter> 93 </Style>
HeaderedWindwo.cs
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class HeaderedWindow : Window 2 { 3 #region 模板中的部分控件名称 4 private const string HeaderContainerName = "PART_HeaderContainer"; 5 private const string MinimizeButtonName = "PART_MinimizeButton"; 6 private const string RestoreButtonName = "PART_RestoreButton"; 7 private const string CloseButtonName = "PART_CloseButton"; 8 private const string TopResizerName = "PART_TopResizer"; 9 private const string LeftResizerName = "PART_LeftResizer"; 10 private const string RightResizerName = "PART_RightResizer"; 11 private const string BottomResizerName = "PART_BottomResizer"; 12 private const string BottomRightResizerName = "PART_BottomRightResizer"; 13 private const string TopRightResizerName = "PART_TopRightResizer"; 14 private const string TopLeftResizerName = "PART_TopLeftResizer"; 15 private const string BottomLeftResizerName = "PART_BottomLeftResizer"; 16 #endregion 17 18 #region 依赖属性 19 public static readonly DependencyProperty ShowDefaultHeaderProperty = 20 DependencyProperty.Register("ShowDefaultHeader", typeof(bool), typeof(HeaderedWindow), new FrameworkPropertyMetadata(true)); 21 22 public static readonly DependencyProperty ShowResizeGripProperty = 23 DependencyProperty.Register("ShowResizeGrip", typeof(bool), typeof(HeaderedWindow), new FrameworkPropertyMetadata(false)); 24 25 public static readonly DependencyProperty CanResizeProperty = 26 DependencyProperty.Register("CanResize", typeof(bool), typeof(HeaderedWindow), new FrameworkPropertyMetadata(true)); 27 28 public static readonly DependencyProperty HeaderProperty = 29 DependencyProperty.Register("Header", typeof(object), typeof(HeaderedWindow), new FrameworkPropertyMetadata(null, OnHeaderChanged)); 30 31 public static readonly DependencyProperty HeaderTemplateProperty = 32 DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(HeaderedWindow), new FrameworkPropertyMetadata(null)); 33 34 public static readonly DependencyProperty HeaderTempateSelectorProperty = 35 DependencyProperty.Register("HeaderTempateSelector", typeof(DataTemplateSelector), typeof(HeaderedWindow), new FrameworkPropertyMetadata(null)); 36 37 public static readonly DependencyProperty IsFullScreenMaximizeProperty = 38 DependencyProperty.Register("IsFullScreenMaximize", typeof(bool), typeof(HeaderedWindow), new FrameworkPropertyMetadata(false)); 39 40 private static void OnHeaderChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 41 { 42 HeaderedWindow win = sender as HeaderedWindow; 43 win.RemoveLogicalChild(e.OldValue); 44 win.AddLogicalChild(e.NewValue); 45 } 46 47 public bool ShowDefaultHeader 48 { 49 get { return (bool)GetValue(ShowDefaultHeaderProperty); } 50 set { SetValue(ShowDefaultHeaderProperty, value); } 51 } 52 53 public bool CanResize 54 { 55 get { return (bool)GetValue(CanResizeProperty); } 56 set { SetValue(CanResizeProperty, value); } 57 } 58 59 public bool ShowResizeGrip 60 { 61 get { return (bool)GetValue(ShowResizeGripProperty); } 62 set { SetValue(ShowResizeGripProperty, value); } 63 } 64 65 public object Header 66 { 67 get { return (object)GetValue(HeaderProperty); } 68 set { SetValue(HeaderProperty, value); } 69 } 70 71 public DataTemplate HeaderTemplate 72 { 73 get { return (DataTemplate)GetValue(HeaderTemplateProperty); } 74 set { SetValue(HeaderTemplateProperty, value); } 75 } 76 77 public DataTemplateSelector HeaderTempateSelector 78 { 79 get { return (DataTemplateSelector)GetValue(HeaderTempateSelectorProperty); } 80 set { SetValue(HeaderTempateSelectorProperty, value); } 81 } 82 83 public bool IsFullScreenMaximize 84 { 85 get { return (bool)GetValue(IsFullScreenMaximizeProperty); } 86 set { SetValue(IsFullScreenMaximizeProperty, value); } 87 } 88 89 #endregion 90 91 static HeaderedWindow() 92 { 93 DefaultStyleKeyProperty.OverrideMetadata(typeof(HeaderedWindow), new FrameworkPropertyMetadata(typeof(HeaderedWindow))); 94 } 95 96 #region 私有变量 97 98 private FrameworkElement headerContainer; 99 private Button minimizeButton; 100 private ToggleButton restoreButton; 101 private Button closeButton; 102 private Thumb topResizer; 103 private Thumb leftResizer; 104 private Thumb rightResizer; 105 private Thumb bottomResizer; 106 private Thumb bottomRightResizer; 107 private Thumb topRightResizer; 108 private Thumb topLeftResizer; 109 private Thumb bottomLeftResizer; 110 #endregion 111 112 #region 重写函数 113 114 public override void OnApplyTemplate() 115 { 116 base.OnApplyTemplate(); 117 headerContainer = GetTemplateChild<FrameworkElement>(HeaderContainerName); 118 headerContainer.MouseLeftButtonDown += HeaderContainerMouseLeftButtonDown; 119 closeButton = GetTemplateChild<Button>(CloseButtonName); 120 closeButton.Click += delegate { Close(); }; 121 restoreButton = GetTemplateChild<ToggleButton>(RestoreButtonName); 122 restoreButton.Checked += delegate { ChangeWindowState(WindowState.Maximized); }; 123 restoreButton.Unchecked += delegate { ChangeWindowState(WindowState.Normal); }; 124 StateChanged += new EventHandler(HeaderedWindowStateChanged); 125 minimizeButton = GetTemplateChild<Button>(MinimizeButtonName); 126 minimizeButton.Click += delegate { ChangeWindowState(WindowState.Minimized); }; 127 topResizer = GetTemplateChild<Thumb>(TopResizerName); 128 topResizer.DragDelta += new DragDeltaEventHandler(ResizeTop); 129 leftResizer = GetTemplateChild<Thumb>(LeftResizerName); 130 leftResizer.DragDelta += new DragDeltaEventHandler(ResizeLeft); 131 rightResizer = GetTemplateChild<Thumb>(RightResizerName); 132 rightResizer.DragDelta += new DragDeltaEventHandler(ResizeRight); 133 bottomResizer = GetTemplateChild<Thumb>(BottomResizerName); 134 bottomResizer.DragDelta += new DragDeltaEventHandler(ResizeBottom); 135 bottomRightResizer = GetTemplateChild<Thumb>(BottomRightResizerName); 136 bottomRightResizer.DragDelta += new DragDeltaEventHandler(ResizeBottomRight); 137 topRightResizer = GetTemplateChild<Thumb>(TopRightResizerName); 138 topRightResizer.DragDelta += new DragDeltaEventHandler(ResizeTopRight); 139 topLeftResizer = GetTemplateChild<Thumb>(TopLeftResizerName); 140 topLeftResizer.DragDelta += new DragDeltaEventHandler(ResizeTopLeft); 141 bottomLeftResizer = GetTemplateChild<Thumb>(BottomLeftResizerName); 142 bottomLeftResizer.DragDelta += new DragDeltaEventHandler(ResizeBottomLeft); 143 } 144 #endregion 145 146 #region 辅助函数 147 148 private T GetTemplateChild<T>(string childName) where T : FrameworkElement 149 { 150 return (GetTemplateChild(childName) as T); 151 } 152 153 /// <summary> 154 /// 鼠标左键单击拖动标题栏,双击窗体状态变化(最大化和还原) 155 /// </summary> 156 /// <param name="sender"></param> 157 /// <param name="e"></param> 158 private void HeaderContainerMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 159 { 160 if (e.ClickCount == 1) 161 { 162 DragMove(); 163 } 164 else 165 { 166 ChangeWindowState(WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized); 167 } 168 } 169 /// <summary> 170 /// 改变窗体状态 171 /// </summary> 172 /// <param name="state">Maximized,Normal,Minimized</param> 173 private void ChangeWindowState(WindowState state) 174 { 175 if (state == WindowState.Maximized) 176 { 177 if (!IsFullScreenMaximize && IsLocationOnPrimaryScreen()) 178 { 179 MaxHeight = SystemParameters.WorkArea.Height; 180 MaxWidth = SystemParameters.WorkArea.Width; 181 } 182 else 183 { 184 MaxHeight = double.PositiveInfinity; 185 MaxWidth = double.PositiveInfinity; 186 } 187 } 188 WindowState = state; 189 } 190 191 private void HeaderedWindowStateChanged(object sender, EventArgs e) 192 { 193 if (WindowState == WindowState.Minimized) 194 { 195 restoreButton.IsChecked = null; 196 } 197 else 198 { 199 restoreButton.IsChecked = WindowState == WindowState.Maximized; 200 } 201 } 202 /// <summary> 203 /// 判断控件是否位于主显示器中 204 /// </summary> 205 /// <returns></returns> 206 private bool IsLocationOnPrimaryScreen() 207 { 208 return Left < SystemParameters.PrimaryScreenWidth && Top < SystemParameters.PrimaryScreenHeight; 209 } 210 211 #endregion 212 213 #region 重置大小 214 private void ResizeBottomLeft(object sender, DragDeltaEventArgs e) 215 { 216 ResizeLeft(sender, e); 217 ResizeBottom(sender, e); 218 } 219 220 private void ResizeTopLeft(object sender, DragDeltaEventArgs e) 221 { 222 ResizeTop(sender, e); 223 ResizeLeft(sender, e); 224 } 225 226 private void ResizeTopRight(object sender, DragDeltaEventArgs e) 227 { 228 ResizeRight(sender, e); 229 ResizeTop(sender, e); 230 } 231 232 private void ResizeBottomRight(object sender, DragDeltaEventArgs e) 233 { 234 ResizeBottom(sender, e); 235 ResizeRight(sender, e); 236 } 237 238 private void ResizeBottom(object sender, DragDeltaEventArgs e) 239 { 240 if (ActualHeight <= MinHeight && e.VerticalChange < 0) 241 { 242 return; 243 } 244 if (double.IsNaN(Height)) 245 { 246 Height = ActualHeight; 247 } 248 Height += e.VerticalChange; 249 } 250 251 private void ResizeRight(object sender, DragDeltaEventArgs e) 252 { 253 if (ActualWidth <= MinWidth && e.HorizontalChange < 0) 254 { 255 return; 256 } 257 if (double.IsNaN(Width)) 258 { 259 Width = ActualWidth; 260 } 261 Width += e.HorizontalChange; 262 } 263 264 private void ResizeLeft(object sender, DragDeltaEventArgs e) 265 { 266 if (ActualWidth <= MinWidth && e.HorizontalChange > 0) 267 { 268 return; 269 } 270 271 if (double.IsNaN(Width)) 272 { 273 Width = ActualWidth; 274 } 275 276 Width -= e.HorizontalChange; 277 Left += e.HorizontalChange; 278 } 279 280 private void ResizeTop(object sender, DragDeltaEventArgs e) 281 { 282 if (ActualHeight <= MinHeight && e.VerticalChange > 0) 283 { 284 return; 285 } 286 if (double.IsNaN(Height)) 287 { 288 Height = ActualHeight; 289 } 290 Height -= e.VerticalChange; 291 Top += e.VerticalChange; 292 } 293 #endregion 294 }
BoolToVisibilityConverter类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class BoolToVisibilityConverter : IValueConverter 2 { 3 #region IValueConverter Members 4 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 5 { 6 return (bool)value ? Visibility.Visible : Visibility.Hidden; 7 } 8 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 9 { 10 throw new NotImplementedException(); 11 } 12 #endregion 13 }