So I built this sample application and using a custom WindowChrome with WPF and C#. Everytime I try to maximize my window using the buttons I made, the maximized window becomes slightly off? Like by a few pixels. What is happening?
<Window x:Class="TestApp.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:TestApp"
mc:Ignorable="d"
Title="TestApp"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
MinHeight="500" MinWidth="940">
<WindowChrome.WindowChrome>
<WindowChrome
ResizeBorderThickness="6"
CaptionHeight="20"
GlassFrameThickness="0"
CornerRadius="0"
/>
</WindowChrome.WindowChrome>
<!-- Application -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="26" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- WindowChrone Header -->
<Grid Background="{StaticResource WindowChromeBrush}" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="RelayC" />
<Button Click="MinimizeWindow" Grid.Column="2" Style="{StaticResource WindowChromeButton}">
<Image Source="{StaticResource window_minimize_icon}"/>
</Button>
<Button Click="MaximizeWindow" Grid.Column="3" Style="{StaticResource WindowChromeButton}">
<Image Source="{StaticResource window_maximize_icon}" />
</Button>
<Button Click="CloseWindow" Grid.Column="4" Style="{StaticResource WindowChromeButton}">
<Image Source="{StaticResource window_close_icon}" />
</Button>
</Grid>
<!--- Main Content -->
<Grid Grid.Row="1">
</Grid>
</Grid>
</Window>
Here is my sample code for the Button Functions:
private void MinimizeWindow(object sender, RoutedEventArgs e) => this.WindowState = WindowState.Minimized;
private void MaximizeWindow(object sender, RoutedEventArgs e) => this.WindowState = WindowState.Maximized;
private void CloseWindow(object sender, RoutedEventArgs e) => this.Close();
What am I doing wrong?
I ended up finding a sort of elegant solution to this problem. I simply assigned a name to the outermost grid, detected whenever it was maximized and added a margin to make sure the application was fully encompassing the screen and not going over. Then, when the screen size changed, I would remove said margin.
Here is some of my code:
Main functions:
private bool isMaximized = false;
private void CheckMaximizeChange(object sender, SizeChangedEventArgs e)
{
if (WindowState == WindowState.Maximized || (isMaximized && WindowState != WindowState.Minimized)) ChangeWindow();
}
private void MaximizeWindow(object sender, RoutedEventArgs e) => this.WindowState ^= WindowState.Maximized;
private void ChangeWindow()
{
isMaximized = !isMaximized;
MaximizeImageButton.Source = FindResource(MaximizeImageButton.Source == FindResource("window_maximize_icon") ? "window_restore_icon" : "window_maximize_icon") as DrawingImage;
MainGrid.Margin = new Thickness(MainGrid.Margin == new Thickness(0) ? 7 : 0);
}
then in the constructor of the application:
SizeChanged += CheckMaximizeChange;
Related
I’m using Material Design In XAML Toolkit C# ,MessageBox in material design WPF C# ,
I need like this or better Design for MessageBox 👌
I’ve tried use DialogHost but this Error happens
No loaded DialogHost instances.
private async void MenuPopupButton_OnClick(object sender, RoutedEventArgs e) {
var sampleMessageDialog = new SampleMessageDialog {
Message = {Text = "Goodbye"}
};
await DialogHost.Show(sampleMessageDialog, "RootDialog");
}
No loaded DialogHost instances.
I have developed one custom message box(using material design controls) in my application.
i'll show you the code below of WPF XAML and C#.
it contains three types of message boxes as below.
Yes,No
Ok
Ok,Cancel
Download code from below link.
https://github.com/sandeepjadhav75502/CustomMessageBoxWPF
WPF XAML Code
Heading
<Window x:Class="EVotingDashBoard.MessageBoxCustom"
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"
mc:Ignorable="d"
Title="MessageBoxWindow" Height="220" Width="500"
WindowStartupLocation="CenterScreen" WindowStyle="None" Background="White"
ResizeMode="CanResize" Topmost="True" ShowInTaskbar="False"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextElement.FontWeight="Regular"
TextElement.FontSize="10"
TextOptions.TextFormattingMode="Ideal"
TextOptions.TextRenderingMode="Auto"
FontFamily="{DynamicResource MaterialDesignFont}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="197*"/>
<ColumnDefinition Width="295*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<materialDesign:Card x:Name="cardHeader" Grid.Row="0" Padding="10" Margin="0" materialDesign:ShadowAssist.ShadowDepth="Depth5" Background="{DynamicResource PrimaryHueDarkBrush}" Foreground="{DynamicResource PrimaryHueDarkForegroundBrush}" Visibility="Visible" Grid.ColumnSpan="2">
<StackPanel>
<TextBlock x:Name="txtTitle" HorizontalAlignment="Center" VerticalAlignment="Stretch" Style="{DynamicResource MaterialDesignTitleTextBlock}" FontSize="20" >Message Title</TextBlock>
</StackPanel>
</materialDesign:Card>
<StackPanel HorizontalAlignment="Right" Margin="0,5,5,0" VerticalAlignment="Top" Grid.Column="1">
<Button x:Name="btnClose" Click="btnClose_Click" Width="35" Height="35" Background="White" Foreground="{DynamicResource PrimaryHueDarkBrush}" Style="{StaticResource MaterialDesignFloatingActionDarkButton}">
<materialDesign:PackIcon Kind="Close" />
</Button>
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="2">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<materialDesign:TransitioningContent>
<materialDesign:TransitioningContent.OpeningEffects >
<materialDesign:TransitionEffect Kind="FadeIn" />
<materialDesign:TransitionEffect Kind="SlideInFromBottom" />
</materialDesign:TransitioningContent.OpeningEffects>
<TextBox x:Name="txtMessage" HorizontalAlignment="Center" IsReadOnly="True" Grid.Row="0" Margin="5" materialDesign:HintAssist.Hint="" FontSize="18" Style="{StaticResource MaterialDesignFloatingHintTextBox}" />
</materialDesign:TransitioningContent>
</Grid>
<Grid Grid.Row="1" Margin="0,20,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnOk" Click="btnOk_Click" Grid.Column="1" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5" Width="100" Content="OK" ToolTip="Ok"/>
<Button x:Name="btnCancel" Click="btnCancel_Click" Grid.Column="2" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5" Width="100" Content="Cancel" ToolTip="Cancel"/>
<Button x:Name="btnYes" Click="btnYes_Click" Grid.Column="1" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5" Width="100" Content="Yes" ToolTip="Yes"/>
<Button x:Name="btnNo" Click="btnNo_Click" Grid.Column="2" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5" Width="100" Content="No" ToolTip="No"/>
</Grid>
</Grid>
</Grid>
</Grid>
</Window>
C# Code Behind
/// <summary>
/// Interaction logic for MessageBoxCustom.xaml
/// </summary>
public partial class MessageBoxCustom : Window
{
public MessageBoxCustom(string Message, MessageType Type, MessageButtons Buttons)
{
InitializeComponent();
txtMessage.Text = Message;
switch (Type)
{
case MessageType.Info:
txtTitle.Text = "Info";
break;
case MessageType.Confirmation:
txtTitle.Text = "Confirmation";
break;
case MessageType.Success:
{
txtTitle.Text = "Success";
}
break;
case MessageType.Warning:
txtTitle.Text = "Warning";
break;
case MessageType.Error:
{
txtTitle.Text = "Error";
}
break;
}
switch (Buttons)
{
case MessageButtons.OkCancel:
btnYes.Visibility = Visibility.Collapsed; btnNo.Visibility = Visibility.Collapsed;
break;
case MessageButtons.YesNo:
btnOk.Visibility = Visibility.Collapsed; btnCancel.Visibility = Visibility.Collapsed;
break;
case MessageButtons.Ok:
btnOk.Visibility = Visibility.Visible;
btnCancel.Visibility = Visibility.Collapsed;
btnYes.Visibility = Visibility.Collapsed; btnNo.Visibility = Visibility.Collapsed;
break;
}
}
private void btnYes_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
private void btnNo_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
}
public enum MessageType
{
Info,
Confirmation,
Success,
Warning,
Error,
}
public enum MessageButtons
{
OkCancel,
YesNo,
Ok,
}
we can call it like
private void Button_Close(object sender, RoutedEventArgs e)
{
bool? Result = new MessageBoxCustom("Are you sure, You want to close
application ?", MessageType.Confirmation, MessageButtons.YesNo).ShowDialog();
if (Result.Value)
{
Application.Current.Shutdown();
}
}
Consider using this package that has the following extra benefit features:
Custom styles for border window, message foreground and background, title foreground and background, border, etc
Button to copy message box details to clipboard
Scrollable message box content
Message content is .NET UIElement which can host any content
I'm trying to get the positions of controls (buttons) but it keeps returning {0;0}. I'm sure there's an explanation for this, but I can't figure out why this happens.
I want the position of the control, relative to the window or a certain container. My buttons are arranged in another grid. Taking the margins of these buttons would just give 0,0 since they're all inside grid cells.
What I tried:
- var point = btnTest.TransformToAncestor(mainGrid).Transform(new Point());
- UIElement container = VisualTreeHelper.GetParent(btnTest) as UIElement;
Point relativeLocation = btnTest.TranslatePoint(new Point(0, 0), mainGrid);
I tried this with a grid as a parent and with a canvas. Everything I try gives me {0,0}. When I change the new Point parameters, the position does change. It stays the same as the parameters.
Small part of my XAML:
<Grid x:Name="mainGrid">
<Grid Name="buttonGrid" Margin="105,64,98.4,97.8">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnTest" Grid.Row="0" Grid.Column="0" Content="Button" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="26" Height="29"/>
<Button x:Name="btnTest2" Grid.Row="1" Grid.Column="1" Content="Button" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="26" Height="29"/>
</Grid>
</Grid>
Your code works perfectly fine, it is the timing that is the issue. The UI elements must be drawn before the position can be retrieved.
The code sample below shows the point extraction running in the constructor with the result 0,0 and then running in the loaded event which returns the desired result 84,78.
<Window x:Class="WpfApp7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Grid x:Name="mainGrid">
<Button x:Name="btnTest" Content="TileButton" HorizontalAlignment="Left" Margin="84,78,0,0" VerticalAlignment="Top" Width="109" Height="103"/>
</Grid>
public MainWindow()
{
InitializeComponent();
GetPoint();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
GetPoint();
}
private void GetPoint()
{
var point = btnTest.TransformToAncestor(mainGrid).Transform(new Point());
UIElement container = VisualTreeHelper.GetParent(btnTest) as UIElement;
Point relativeLocation = btnTest.TranslatePoint(new Point(0, 0), mainGrid);
MessageBox.Show($"X = {relativeLocation.X} Y = {relativeLocation.Y}");
}
Is there a way to have a xaml page scroll to a particular object on a button click? For example, I have three buttons at the top of my page. I would like each button to move the scrollviewer to the top, middle, and bottom section of the page. How can I make this happen? Thanks!
I try to create the Xaml and to solve the problem. This is my solution.
This is the Xaml code.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button HorizontalAlignment="Left" Content="Top" Click="Button_Click" ></Button>
<Button HorizontalAlignment="Center" Content="Center" Click="Button_Click_1" ></Button><Button Content="Botton" HorizontalAlignment="Right" Click="Button_Click_2" ></Button>
<ScrollViewer Grid.Row="1" Name="MyScrollViewer" MaxZoomFactor="9">
<StackPanel>
<TextBlock Name="TextBlock" Height="20"> </TextBlock>
<Rectangle Height="300" Width="100" Fill="BlanchedAlmond"></Rectangle>
<Rectangle Height="300" Width="100" Fill="Blue"></Rectangle>
<Rectangle Height="300" Width="100" Fill="BlueViolet"></Rectangle>
<Rectangle Height="300" Width="100" Fill="Chartreuse"></Rectangle>
<Rectangle Height="300" Width="100" Fill="Crimson"></Rectangle>
</StackPanel>
</ScrollViewer>
</Grid>
And this is the .cs Code
private void Button_Click(object sender, RoutedEventArgs e)
{
MyScrollViewer.ScrollToVerticalOffset(0);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var scrollableHeight = MyScrollViewer.ScrollableHeight;
var height= scrollableHeight / 2;
MyScrollViewer.ScrollToVerticalOffset(height);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
MyScrollViewer.ScrollToVerticalOffset(MaxHeight);
}
}
I observe Mouse.MouseDown and PreviewMouseLeftButtonDown are only raised when the mouse is clicked in a cell that contains a UIElement, e.g.:
XAML
<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="WpfApplication5.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Width="300" Height="300">
<Grid Mouse.MouseDown="Grid_MouseDown" PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="2" Grid.RowSpan="2" Fill="Red"/>
</Grid>
</Window>
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("PreviewMouseLeftButtonDown raised!");
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("MouseDown raised!");
}
}
The lines are only written to Debug when the red rectangle is clicked. How can I get the events, or at least one of them, to be raised the grid contains nothing?
I do not know the cause of the issue, but as a workaround giving the Grid a background, even Transparent, seems to make the events be raised!
<Grid Background="Transparent" Mouse.MouseDown="Grid_MouseDown" PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown">
GridSplitterControl.xaml
<sdk:GridSplitter x:Class="JustLogIt.Common.GridSplitterControl"
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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d">
<sdk:GridSplitter.Template>
<ControlTemplate TargetType="sdk:GridSplitter">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<telerik:RadButton Grid.Row="0"
Width="10"
Height="20"
HorizontalAlignment="Center"
Click="Click"
Cursor="Hand" />
<Border Grid.Row="1"
BorderBrush="LightGray"
BorderThickness="5" />
</Grid>
</ControlTemplate>
</sdk:GridSplitter.Template>
</sdk:GridSplitter>
GridSplitterControl.xaml.cs
public partial class GridSplitterControl : GridSplitter
{
GridLength AutoSize = new GridLength(1.0, GridUnitType.Auto);
GridLength ZeroSize = new GridLength(0.0);
public ColumnDefinition Left{ set; get;}
public GridSplitterControl()
{
InitializeComponent();
}
public GridSplitterControl(ColumnDefinition ColLeft)
{
InitializeComponent();
Left = ColLeft;
}
public void Click(object sender, RoutedEventArgs e)
{
if (Left != null)
{
Left.MinWidth = 10.0;
if ((Left.Width.Value + 10) == Left.MinWidth)
Left.Width = AutoSize;
else if (Left.Width.Value != AutoSize.Value)
Left.Width = AutoSize;
else Left.Width = ZeroSize;
}
//ClickNotify(sender, e);
}
public event EventHandler ClickCompleted;
private void ClickNotify(object senderAIF, RoutedEventArgs eAIF)
{
if (ClickCompleted != null)
ClickCompleted(senderAIF, eAIF);
}
}
The Click event can work, but I have no idea to set the Left(ColumnDefinition) in xaml file which used this Element.
<Grid x:Name="LayoutRoot1"
Grid.Row="1"
Margin="5"
Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LvCol_10" Width="*" />
<ColumnDefinition x:Name="LvCol_11" Width="*" />
</Grid.ColumnDefinitions>
<Mylayout:GridSplitterControl x:Name="GridSplitter_Left"
Grid.RowSpan="7"
Grid.Column="0"
Width="10"
VerticalAlignment="Stretch"
IsEnabled="True"
Left=? /> < !-- How to set "LvCol_11" in here? -->
</Grid>`
It seems like that you want to set the grid.row as property which is used when the button click.
Maybe you can try this...
GridSplitterControl.xaml.cs
private void UI_Loaded(object sender, RoutedEventArgs e)
{
if (sender is GridSplitter)
{
Grid ParentGrid = this.ParentOfType<Grid>();
SetLocation(ParentGrid);
}
}
public void SetLocation(Grid p_Layout)
{
int index = Grid.GetColumn(this);
ColumnDefinition ColLocation = p_Layout.ColumnDefinitions[index];
ColLocation.MinWidth = 10;
Left = ColLocation;
}
Becarefully, besure your element's parent(Up one level) is grid.
If parent is stackPanel, border, or rectangle, it will be not working, maybe.