I'm quite new to WPF and am trying to build a GUI in Blend, but I'm running into all sorts of issues.
I want my finished product to look like this: https://imgur.com/a/BU8Te
(the red is just a placeholder for icons).
Here is the XAML I've got so far:
<Window x:Class="GUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:GUI"
mc:Ignorable="d"
Title="GUI"
Height="840"
Width="920"
WindowStyle="none"
ResizeMode="CanResizeWithGrip"
AllowsTransparency="true"
MouseLeftButtonDown="Window_MouseLeftButtonDown"
WindowStartupLocation="CenterScreen"
Background="Transparent"
MaxWidth="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
MaxHeight="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}">
<Border x:Name="shadow">
<Grid x:Name="grid" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="2"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="#F9F9F9" />
<Border Grid.Row="1" Background="#F9F9F9" />
<Border Grid.Row="2" Background="#E9E9E9" />
<DockPanel Grid.Row="0" LastChildFill="False">
<Button x:Name="btnClose"
DockPanel.Dock="Right"
VerticalAlignment="Center"
Height="20" Width="20"
Click="btnClose_Click"
Style="{DynamicResource CloseButton}">
<Path Data="m 357.0883 499.0572 12.62375 12.6275 5.31375 -5.31625 -12.62625 -12.62625 12.62625 -12.61875 -5.31375 -5.3125 -12.62375 12.62 -12.6325 -12.62 -5.30375 5.3125 12.6175 12.61875 -12.6175 12.62625 5.30375 5.31625 12.6325 -12.6275 z" Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="btnMaximise"
DockPanel.Dock="Right"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="20" Width="20"
Click="btnMaximise_Click"
Style="{DynamicResource TitleButton}">
<Path Data="M4.3685131,23.127279L4.3685131,47.283243 47.117023,47.283243 47.117023,23.127279z M0,10.684L53.755001,10.684 53.755001,51.668001 0,51.668001z M8.5679998,0L58.668022,0 64,0 64,5.6864691 64,45.317999 58.668022,45.317999 58.668022,5.6864691 8.5679998,5.6864691z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="btnMinimise"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DockPanel.Dock="Right"
Height="20" Width="20"
Click="btnMinimise_Click"
VerticalContentAlignment="Bottom"
Style="{DynamicResource TitleButton}">
<Button.Content>
<Path Data="M0,20L53.333,20 53.333,8.888 0,8.888z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,5"></Path>
</Button.Content>
</Button>
</DockPanel>
</Grid>
</Border>
</Window>
But when I maximise the window, the top left corner is off my screen (-15, -15 maybe?) and the bottom right corner is also too far up and left because of this. I modified some code that I found online (can't remember the source) which fixed this:
private bool isMaximized;
private Rect normalBounds;
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized && !isMaximized)
{
// max
WindowState = WindowState.Normal;
isMaximized = true;
normalBounds = RestoreBounds;
Height = SystemParameters.WorkArea.Height;
MaxHeight = Height;
MinHeight = Height;
Top = 0;
Left = 0;
Width = SystemParameters.WorkArea.Width;
SetMovable(false);
}
else if (WindowState == WindowState.Maximized && isMaximized)
{
// min
WindowState = WindowState.Normal;
isMaximized = false;
MaxHeight = Double.PositiveInfinity;
MinHeight = 0;
Top = normalBounds.Top;
Left = normalBounds.Left;
Width = normalBounds.Width;
Height = normalBounds.Height;
SetMovable(true);
}
}
private void SetMovable(bool enable)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (enable)
source.RemoveHook(WndProc);
else
source.AddHook(WndProc);
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
switch (msg)
{
case WM_SYSCOMMAND:
int command = wParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
handled = true;
break;
}
return IntPtr.Zero;
}
Now that works perfectly, but I'm really struggling to get this to work with a drop shadow on the window. When I add a 10px border to the window and set the dropshadow on this, I get the resizing icon in my border and not in my window:
https://imgur.com/a/S9oLK
I also had to modify the StateChanged event method to hide the border when maximised:
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized && !isMaximized)
{
// max
WindowState = WindowState.Normal;
isMaximized = true;
normalBounds = RestoreBounds;
Height = SystemParameters.WorkArea.Height;
MaxHeight = Height;
MinHeight = Height;
Top = 0;
Left = 0;
Width = SystemParameters.WorkArea.Width;
SetMovable(false);
this.grid.Margin = new Thickness(0);
this.BorderThickness = new Thickness(0);
}
else if (WindowState == WindowState.Maximized && isMaximized)
{
// min
WindowState = WindowState.Normal;
isMaximized = false;
MaxHeight = Double.PositiveInfinity;
MinHeight = 0;
Top = normalBounds.Top;
Left = normalBounds.Left;
Width = normalBounds.Width;
Height = normalBounds.Height;
SetMovable(true);
this.grid.Margin = new Thickness(10);
this.BorderThickness = new Thickness(10);
}
}
But this obviously doesn't work when the window is snapped to the edge of a screen: https://i.imgur.com/pGC1fio.png
To summarise, my issues are:
Resize grabber is in border not main window.
I don't know how to hide the border when the window is snapped to the edge of the screen.
Is there a simple way to fix this? I feel like I'm having to create a very hacky fix for all of this and thought it would be a lot easier to implement a custom window like this.
Thanks in advance for any help.
Related
I been working with winforms, so my knowledge of WFP is non existent, this is something i am trying to test.
In code I am generating few buttons and placing them on Canvas. Than after clik on any button, i am moving that button around, and after second click button should stay at the position where mouse cursor was when clicked.
If mouse cursor go outside canvas then button will stop follow it.
My problem is, that button is moving, but only when mouse cursor is over that button or any other control, but it is not moving while mouse cursor is traveling over Canvas.
XAML
<Window x:Class="WpfTestDrag.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTestDrag"
mc:Ignorable="d"
Title="MainWindow" Height="522" Width="909">
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="130*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Canvas Grid.Column="1" Grid.Row="1" x:Name="cnvTest" Width="auto" Height="auto" PreviewMouseMove="CnvTest_PreviewMouseMove"/>
<TextBlock x:Name="txbStatus" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2"/>
</Grid>
</Window>
C#
public partial class MainWindow : Window
{
Button bts;
Boolean isUsed = false;
public MainWindow()
{
InitializeComponent();
CreateButtons();
}
private void CreateButtons()
{
var xPos = 10.0;
var yPos = 15.0;
var Rnd = new Random();
for (int i = 0; i < 3; i++)
{
var btn = new Button();
btn.Name = "btn" + i;
btn.Content = "Button - " + i;
btn.Tag = "Tag" + i;
btn.Width = 150;
btn.Height = 150;
btn.Click += Btn_Click;
Canvas.SetLeft(btn, xPos);
Canvas.SetTop(btn, yPos);
cnvTest.Children.Add(btn);
xPos = xPos + btn.Width + Rnd.Next(-15,40);
yPos = yPos + btn.Height + Rnd.Next(-15, 40);
}
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
bts = sender as Button;
if (isUsed == false)
{
isUsed = true;
}
else
{
isUsed = false;
}
}
private void CnvTest_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point p = Mouse.GetPosition(cnvTest);
if (isUsed == true)
{
Canvas.SetLeft(bts, p.X);
Canvas.SetTop(bts, p.Y);
txbStatus.Text = bts.Name.ToString() + " isUsed:" + isUsed.ToString() + " -> xPos:" + p.X.ToString() + " yPos:" + p.Y.ToString();
}
}
}
Should I use something else than Canvas for this?
You should set the Background property of the Canvas to Transparent (or any other Brush) for it to respond to the mouse events:
<Canvas Grid.Column="1" Grid.Row="1" x:Name="cnvTest" Width="auto" Height="auto" PreviewMouseMove="CnvTest_PreviewMouseMove"
Background="Transparent"/>
I am binding window DragMove event to the border control for moving the window. Propert is local:EnableDragHelper.EnableDrag="True" you can check design below.
<Border Grid.Row="0" BorderThickness="1" BorderBrush="Black" Background="#467EAF" Name="borderHeader" local:EnableDragHelper.EnableDrag="True">
<StackPanel Grid.Row="0" VerticalAlignment="Center">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" Content="{Binding InspectionHistoryModel.CurrentDateTime,Mode=TwoWay}" FontWeight="Bold" Foreground="White" FontSize="18" Margin="5,0,0,0"></Label>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Name="popupTaregetextblock" Margin="10,0,0,0" VerticalAlignment="Center">
<Hyperlink FontSize="20" Foreground="White" Command="{Binding ShowHideHeaderPopupCommand}" CommandParameter="onDuty"><TextBlock Text="{Binding InspectionHistoryModel.HeaderDutyText, Mode=TwoWay}" VerticalAlignment="Center" FontWeight="Bold" FontSize="18" Foreground="White"> </TextBlock></Hyperlink>
</TextBlock>
</Grid>
</StackPanel>
</Border>
Comamnd of Hyperlink (which put in inside of the border) is not working. How to possible this? Drag Code is
private static void UIElementOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
var uiElement = sender as UIElement;
if (uiElement != null)
{
if (mouseEventArgs.LeftButton == MouseButtonState.Pressed)
{
DependencyObject parent = uiElement;
int avoidInfiniteLoop = 0;
// Search up the visual tree to find the first parent window.
while ((parent is Window) == false)
{
parent = VisualTreeHelper.GetParent(parent);
avoidInfiniteLoop++;
if (avoidInfiniteLoop == 1000)
{
// Something is wrong - we could not find the parent window.
return;
}
}
var window = parent as Window;
if (window.WindowState == WindowState.Maximized)
{
var mouseX = mouseEventArgs.GetPosition(window).X;
var width = window.RestoreBounds.Width;
var x = mouseX - width / 2;
if (x < 0)
{
x = 0;
}
else
if (x + width > SystemParameters.PrimaryScreenWidth)
{
x = SystemParameters.PrimaryScreenWidth - width;
}
window.WindowState = WindowState.Normal;
window.Left = x;
window.Top = 0;
// window.Width = window.ActualWidth;
// window.Height = window.ActualHeight;
// window.Left = 0;
// window.Top = 0;
// window.WindowStartupLocation = WindowStartupLocation.Manual;
// window.WindowState = WindowState.Normal;
}
window.DragMove();
}
}
}
i tried this Answer and implement it to my code, and here is my code :
XAML
<Window x:Class="DSLayout.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:tk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:DSLayout"
Title="MainWindow" Height="720" Width="1280" ResizeMode="NoResize">
<Window.Resources>
<local:BrushColorConverter x:Key="BrushColorConverter"/>
</Window.Resources>
<Grid>
<Border BorderBrush="Silver" BorderThickness="1" Name="borderHeader" Margin="12,12,12,636" />
<Border BorderBrush="Silver" BorderThickness="1" Name="borderEditor" Margin="12,69,850,12">
<Canvas>
<Border BorderBrush="Silver" BorderThickness="1" Canvas.Left="24" Canvas.Top="20" Height="59" Name="border1" Width="355"></Border>
<Canvas Height="59" Canvas.Left="26" Canvas.Top="20"></Canvas>
<TextBlock Name="textBlock1" Text="Color Palette" Height="31" Width="197" FontSize="22" Canvas.Left="40" Canvas.Top="34" />
<tk:ColorPicker x:Name="ColorPalette" ColorMode="ColorCanvas"
SelectedColor="{Binding ElementName=Layout,
Path=Background,
Converter={StaticResource BrushColorConverter}}"
Canvas.Left="243" Canvas.Top="34" Height="31" />
<Button Grid.Row="1" Content="Add Image" Click="AddButtonClick" Canvas.Left="24" Canvas.Top="100" Height="43" Width="104" />
<Border BorderBrush="Silver" BorderThickness="1" Canvas.Left="24" Canvas.Top="227" Height="350" Name="border3" Width="355">
<Canvas>
<TextBlock Canvas.Left="15" Canvas.Top="27" Height="23" Name="textBlock2" Text="X-Pos " FontSize="16" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="27" FontSize="16" Height="23" Name="textBlock3" Text="Y-Pos " Width="53" />
<Label Name="posX" Height="23" Width="83" Canvas.Left="74" Canvas.Top="27" />
<Label Name="posY" Canvas.Left="233" Canvas.Top="27" Height="23" Width="83" />
<TextBlock Canvas.Left="15" Canvas.Top="68" FontSize="16" Height="23" Name="textBlock4" Text="Width" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="68" FontSize="16" Height="23" Name="textBlock5" Text="Height" Width="53" />
<Label Name="imgHeight" Canvas.Left="74" Canvas.Top="68" Height="23" Width="83" />
<Label Name="imgWidth" Canvas.Left="233" Canvas.Top="68" Height="23" Width="83" />
<!--<TextBlock Canvas.Left="15" Canvas.Top="169" FontSize="16" Height="23" Name="textBlock4" Text="Height" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="169" FontSize="16" Height="23" Name="textBlock5" Text="Width" Width="53" />
<TextBox Canvas.Left="74" Canvas.Top="169" Height="23" Name="textBox3" Width="83" />
<TextBox Canvas.Left="233" Canvas.Top="169" Height="23" Name="textBox4" Width="83" />-->
</Canvas>
</Border>
</Canvas>
</Border>
<Border BorderBrush="Silver" BorderThickness="1" Name="borderLayout" Margin="446,69,12,12">
<Canvas x:Name="Layout" Background="White" AllowDrop="True" ClipToBounds="True"
MouseLeftButtonDown="MouseLeftButtonDown"
MouseLeftButtonUp="MouseLeftButtonUp"
MouseMove="MouseMove">
</Canvas>
</Border>
</Grid>
CS
namespace DSLayout
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public int imgX { get; set; }
public int imgY { get; set; }
private void AddButtonClick(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.OpenFileDialog();
dialog.Filter =
"Image Files (*.jpg; *.png; *.jpeg; *.gif; *.bmp)|*.jpg; *.png; *.jpeg; *.gif; *.bmp";
if ((bool)dialog.ShowDialog())
{
var bitmap = new BitmapImage(new Uri(dialog.FileName));
var image = new Image { Source = bitmap };
this.imgX = bitmap.PixelWidth;
this.imgY = bitmap.PixelWidth;
Canvas.SetLeft(image, 0);
Canvas.SetTop(image, 0);
Layout.Children.Add(image);
imgHeight.Content = bitmap.PixelHeight;
imgWidth.Content = bitmap.PixelWidth;
}
}
private Image draggedImage;
private Point mousePosition;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var image = e.Source as Image;
if (image != null && Layout.CaptureMouse())
{
mousePosition = e.GetPosition(Layout);
draggedImage = image;
Panel.SetZIndex(draggedImage, 1);
}
}
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (draggedImage != null)
{
Layout.ReleaseMouseCapture();
Panel.SetZIndex(draggedImage, 0);
draggedImage = null;
}
}
private void MouseMove(object sender, MouseEventArgs e)
{
if (draggedImage != null)
{
var position = e.GetPosition(Layout);
var offset = position - mousePosition;
mousePosition = position;
if (mousePosition.X > 0 && mousePosition.Y > 0)
{
Canvas.SetLeft(draggedImage, Canvas.GetLeft(draggedImage) + offset.X);
Canvas.SetTop(draggedImage, Canvas.GetTop(draggedImage) + offset.Y);
}
posX.Content = Canvas.GetLeft(draggedImage);
posY.Content = Canvas.GetTop(draggedImage);
}
}
}
}
so i tried using the ClipToBound="True" but it'll missing if i drag to outside the canvas. so i tried to limit it using if (mousePosition.X > 0 && mousePosition.Y > 0) works but not that i want because it will go outside the canvas if i drag it to the left and i drag from the right point of the image.
my idea is to make the draggedImage to be my cursor so with if (mousePosition.X > 0 && mousePosition.Y > 0) it will prevent draggedImage to go outside the canvas. is that possible to do that?
or any simple idea to solve this?
EDIT :
i tried using this code but it works but its not really good because when i drag it out side the canvas it'll move like bouncy from pos -1 to 0.
if (Canvas.GetLeft(draggedImage) <= 0)
{
Canvas.SetLeft(draggedImage, 0);
}
if (Canvas.GetTop(draggedImage) <= 0)
{
Canvas.SetTop(draggedImage, 0);
}
if (Canvas.GetLeft(draggedImage) + this.imgX >= 800)
{
Canvas.SetLeft(draggedImage, 800 - this.imgX);
}
if (Canvas.GetTop(draggedImage) +this.imgY >= 600)
{
Canvas.SetTop(draggedImage, 600 - this.imgY);
}
When you drag an item you change it's X and Y position by specifying Canvas's attached properties Canvas.Left and Canvas.Top. So it is easy to ensure that the dragged element does not get dragged outside it's panel.
double canvasSize = 800;
double newLeft = Canvas.GetLeft(draggedImage) + offset.X;
double newTop = Canvas.GetTop(draggedImage) + offset.Y;
if (newLeft < 0)
newLeft = 0;
else if (newLeft + draggedImage.ActualWidth > canvasSize)
newLeft = canvasSize - draggedImage.ActualWidth;
if (newTop < 0)
newTop = 0;
else if (newTop + draggedImage.ActualHeight > canvasSize)
newTop = canvasSize - draggedImage.ActualHeight;
Canvas.SetLeft(draggedImage, newLeft);
Canvas.SetTop(draggedImage, newTop);
This will check if the element you drag is going outside of the Canvas.
I have wired Manipulation events with the listviewitem to capture left swipe and right swipe. But when I try to scroll down the listview, it does not work! The manipulation events get fired and the listview does not scroll!
This is the listview Datatemplate
<Grid Height="60" Width="380" Margin="0,0,0,1">
<Grid x:Name="ItemGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Width="380" Height="60" Background="Orange" Canvas.ZIndex="2"
ManipulationMode="TranslateX" ManipulationStarted="On_ChannelItem_ManipulationStarted" ManipulationDelta="On_ChannelItem_ManipulationDelta" ManipulationCompleted="OnChannelItemManipulationCompleted">
<TextBlock x:Name="titleTextBlock" Margin="20,0,0,0" Canvas.ZIndex="2" VerticalAlignment="Center" TextAlignment="Left" FontSize="25" >
</TextBlock>
</Grid>
<Grid x:Name="DelGrid" Opacity="0.0" HorizontalAlignment="Right" VerticalAlignment="Center" Height="60" Background="Red" Canvas.ZIndex="-1" Tapped="On_ChannelDelete_Tap" Width="380">
<Button Content="X" FontSize="25" Canvas.ZIndex="-1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="380" BorderThickness="0" />
</Grid>
</Grid>
This is the manipulation events
private void OnChannelItemManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
Grid ChannelGrid = (Grid)sender;
Grid DeleteGrid = (Grid)((Grid)(ChannelGrid.Parent)).Children[1];
double dist = e.Cumulative.Translation.X;
if (dist < -100) // Swipe left
{
Storyboard SwipeLeft = new Storyboard();
DoubleAnimation OpacityAnimation = new DoubleAnimation();
OpacityAnimation.EnableDependentAnimation = true;
OpacityAnimation.From = 0.0;
OpacityAnimation.To = 1.0;
OpacityAnimation.BeginTime = TimeSpan.FromMilliseconds(0);
OpacityAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(1));
Storyboard.SetTarget(OpacityAnimation, DeleteGrid);
Storyboard.SetTargetProperty(OpacityAnimation, "Opacity");
SwipeLeft.Children.Add(OpacityAnimation);
DoubleAnimation WidthAnimation = new DoubleAnimation();
WidthAnimation.EnableDependentAnimation = true;
WidthAnimation.From = 380;
WidthAnimation.To = 0;
WidthAnimation.BeginTime = TimeSpan.FromMilliseconds(30);
WidthAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(WidthAnimation, ChannelGrid);
Storyboard.SetTargetProperty(WidthAnimation, "Width");
SwipeLeft.Children.Add(WidthAnimation);
SwipeLeft.Begin();
}
else if (dist > 100) // Swipe right
{
Storyboard SwipeRight = new Storyboard();
ColorAnimation changeColorAnimation = new ColorAnimation();
changeColorAnimation.EnableDependentAnimation = true;
changeColorAnimation.To = Colors.Green;
changeColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(changeColorAnimation, ChannelGrid);
PropertyPath p = new PropertyPath("(ChannelGrid.Background).(SolidColorBrush.Color)");
Storyboard.SetTargetProperty(changeColorAnimation, p.Path);
SwipeRight.Children.Add(changeColorAnimation);
SwipeRight.Begin();
}
}
How do I enable the normal listview scrolling as well as the swipe? Vertical Scrolling is possible when I remove the manipulation events
Update your manipulation mode to include System:
ManipulationMode="TranslateX,System"
Is there a way in WPF where I can remove the main window's border, yet allow that window to be resized (without grip)?
I realized there's a way to do this scenario by setting resize mode to CanResizeWithGrip. However, I want to be able to do it with the resize mode set to CanResize.
I tried setting the following:
ResizeMode="CanResize"
WindowStyle="None"
AllowsTransparency="True"
However, by setting AllowsTransparency, it removes the ability to resize without the grip. Any ideas how I can pull this off?
I also should note that I can't set AllowsTransparency to true anyway, because I am using a winformshost control in my window, which is not shown when AllowsTransparency is true.
I know this is an old question, but I just wanted to put up a working sample for newcomers.
Xaml Window:
<Window x:Class="CustomWindowDemo.DemoCustomWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CustomWindowDemo"
mc:Ignorable="d"
Title="DemoCustomWindow" Height="300" Width="300" Background="{x:Null}" AllowsTransparency="True" WindowStyle="None">
<Window.Resources>
<Style x:Key="BorderThumb" TargetType="Thumb">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Rectangle MinWidth="4" MinHeight="4" StrokeThickness="0">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.HighlightColorKey}}" Opacity="0.05"/>
</Rectangle.Fill>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border BorderBrush="#55FFFFFF" BorderThickness="1" CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border MouseMove="Header_MouseMove" DockPanel.Dock="Top" Height="32" Grid.Row="1" Grid.Column="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,3">
<GradientStop Color="#3BB2EA" Offset="0" />
<GradientStop Color="#EFF7FA" Offset="0.3" />
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
<Button x:Name="btn_Minimize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Click="btn_Minimize_Click" Grid.Column="1">
<Image Source="Resources/Ahmadhania-Spherical-Minimize.ico"/>
</Button>
<Button x:Name="btn_Maximize" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="2" Click="btn_Maximize_Click">
<Image Source="Resources/1412181205_61002.ico"/>
</Button>
<Button x:Name="btn_Close" Background="{x:Null}" BorderBrush="{x:Null}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0" Grid.Column="3" Click="btn_Close_Click">
<Image Source="Resources/Ahmadhania-Spherical-Close(1).ico"/>
</Button>
</Grid>
</Border>
<Thumb x:Name="ThumbBottom" DragDelta="ThumbBottom_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}" Margin="3,0" Grid.ColumnSpan="3" Grid.Row="3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTop" DragDelta="ThumbTop_DragDelta" HorizontalAlignment="Stretch" Cursor="SizeNS" Grid.Column="0" Background="{x:Null}" Margin="3,0" Grid.ColumnSpan="3" Height="4" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbBottomRightCorner" DragDelta="ThumbBottomRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNWSE" Grid.Row="3" Grid.Column="3" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTopRightCorner" DragDelta="ThumbTopRightCorner_DragDelta" HorizontalAlignment="Right" Cursor="SizeNESW" Grid.Row="0" Grid.Column="2" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbTopLeftCorner" DragDelta="ThumbTopLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNWSE" Grid.Row="0" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
<Thumb x:Name="ThumbBottomLeftCorner" DragDelta="ThumbBottomLeftCorner_DragDelta" HorizontalAlignment="Left" Cursor="SizeNESW" Grid.Row="3" Grid.Column="0" Background="{x:Null}" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}" />
<Thumb x:Name="ThumbRight" DragDelta="ThumbRight_DragDelta" Cursor="SizeWE" Grid.Column="2" Grid.RowSpan="4" Background="{x:Null}" Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Thumb x:Name="ThumbLeft" DragDelta="ThumbLeft_DragDelta" Cursor="SizeWE" Grid.Column="0" Grid.RowSpan="4" HorizontalContentAlignment="Right" Background="{x:Null}" Margin="0,3" Style="{Binding Mode=OneWay, Source={StaticResource BorderThumb}}"/>
<Grid x:Name="Grid_Content" Background="#EFF7FA" Grid.Row="2" Grid.Column="1">
</Grid>
</Grid>
</Border>
</Window>
C# code behind:
using System.Windows.Interop;
using winforms = System.Windows.Forms;
namespace CustomWindowDemo
{
/// <summary>
/// Interaction logic for DemoCustomWindow.xaml
/// </summary>
public partial class DemoCustomWindow : Window
{
bool Maximized = false;
int NormalWidth = 0;
int NormalHeight = 0;
int NormalX = 0;
int NormalY = 0;
public DemoCustomWindow()
{
InitializeComponent();
}
#region Header & Resize
void Header_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
this.DragMove();
}
void ThumbBottomRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbTopRightCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void ThumbTopLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void ThumbBottomLeftCorner_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbRight_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Width + e.HorizontalChange > 10)
this.Width += e.HorizontalChange;
}
void ThumbLeft_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Left + e.HorizontalChange > 10)
{
this.Left += e.HorizontalChange;
this.Width -= e.HorizontalChange;
}
}
void ThumbBottom_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Height + e.VerticalChange > 10)
this.Height += e.VerticalChange;
}
void ThumbTop_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (this.Top + e.VerticalChange > 10)
{
this.Top += e.VerticalChange;
this.Height -= e.VerticalChange;
}
}
void btn_Minimize_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
void btn_Maximize_Click(object sender, RoutedEventArgs e)
{
if (Maximized == true)
{
this.Width = NormalWidth;
this.Height = NormalHeight;
this.Left = NormalX;
this.Top = NormalY;
Maximized = false;
Thumbs();
}
else
{
NormalX = (int)this.Left;
NormalY = (int)this.Top;
NormalHeight = (int)this.Height;
NormalWidth = (int)this.Width;
this.Left = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Left;
this.Top = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Top;
this.Width = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Width;
this.Height = winforms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Height;
Maximized = true;
Thumbs();
}
}
void btn_Close_Click(object sender, RoutedEventArgs e)
{
Close();
}
void Thumbs()
{
if (Maximized == true)
{
ThumbBottom.Visibility = Visibility.Collapsed;
ThumbLeft.Visibility = Visibility.Collapsed;
ThumbTop.Visibility = Visibility.Collapsed;
ThumbRight.Visibility = Visibility.Collapsed;
ThumbTopLeftCorner.Visibility = Visibility.Collapsed;
ThumbTopRightCorner.Visibility = Visibility.Collapsed;
ThumbBottomLeftCorner.Visibility = Visibility.Collapsed;
ThumbBottomRightCorner.Visibility = Visibility.Collapsed;
}
else
{
ThumbBottom.Visibility = Visibility.Visible;
ThumbLeft.Visibility = Visibility.Visible;
ThumbTop.Visibility = Visibility.Visible;
ThumbRight.Visibility = Visibility.Visible;
ThumbTopLeftCorner.Visibility = Visibility.Visible;
ThumbTopRightCorner.Visibility = Visibility.Visible;
ThumbBottomLeftCorner.Visibility = Visibility.Visible;
ThumbBottomRightCorner.Visibility = Visibility.Visible;
}
}
#endregion
}
}
This can happen if ResizeBorderThickness is set to 0.
It can be set to a positive value in XAML like this:
<WindowChrome>
<WindowChrome.ResizeBorderThickness>
<Thickness>1</Thickness>
</WindowChrome.ResizeBorderThickness>
</WindowChrome>
You can use the WPF customizable window library, available here: http://wpfwindow.codeplex.com/
Then, when using the library's window type, you can set the same properties as you listed above
<CustomWindow:EssentialWindow x:Class="CustomWindowDemo.DemoEssentialWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CustomWindow="clr-namespace:CustomWindow;assembly=CustomWindow"
AllowsTransparency="True" ResizeMode="CanResize" WindowStyle="None" Title="EssentialWindow"
Height="300" Width="250">
The user needs something to interact with to resize the window. If you don't like the default border or grip, you'll need to add some other control with a click and drag behavior that resizes the window. Perhaps a line on each edge of the window?
The simplest, but maybe too simple is
this.MouseLeftButtonDown += delegate { this.DragMove(); };