Message freezes the UI application without using the pop-up messagebox - wpf

We are working with WPF. And we have an application with multiple screens and a tree in the left.
In one of them, the user add, edit and delete an node in that tree.
So, We need to show the user a message when he press delete message, if he really wants to delete or not (Yes/Cancel) message, which it needs to freeze the whole application. Then the user is forced to decide.
In the same time, we don't want a pop-up message. We need something like Adorner.
Shows a gray background (which means the whole application has freezed) and we can host a border with a message inside it.
We need alternatives options for Adorner.

You may use something like this
<Window x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Border Name="msg" Background="#20A0A0A0" Visibility="Hidden">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Margin="10" Click="Button_Click_1">Yes</Button>
<Button Margin="10" Click="Button_Click_1">No</Button>
</StackPanel>
</Border>
<Border Name="main">
<StackPanel>
<TextBlock Text="tex"/>
<Button Click="Button_Click">Delete</Button>
<Button>Another button</Button>
</StackPanel>
</Border>
</Grid>
</Window>
private void Button_Click(object sender, RoutedEventArgs e)
{
msg.Visibility = System.Windows.Visibility.Visible;
main.IsEnabled = false;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
msg.Visibility = System.Windows.Visibility.Hidden;
main.IsEnabled = true;
}

Related

XAML: move the cursor in textbox automatically

I dont know if this works but is there any chance to move the cursor inside a Textbox automaticaly for one position(1 space bar click). For example:
I run the application and the cursor inside the Textbox moves automatically for one space bar
my textbox:
<TextBox TextChanged="Searchbox_TextChanged" x:Name="Testing" Margin="2" Grid.Row="1" Text="{Binding SearchSmthg, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalContentAlignment="Center" Controls:TextboxHelper.ClearTextButton="True" Controls:TextboxHelper.Watermark="Search ..."/>
use CaretIndex and FocusManager:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid FocusManager.FocusedElement="{Binding ElementName=Focustext}">
<TextBox x:Name="Focustext" Text=" " CaretIndex="1" MaxHeight="25" />
</Grid>
</Window>
Edit: add a GotFocus event handler and set CaretIndex=1 there
XAML:
<TextBox GotFocus="Testing_GotFocus"
Code Behind:
private void Testing_GotFocus(object sender, RoutedEventArgs e)
{
//make sure your Textbox is not empty..
Testing.CaretIndex = 1;
}

WPF window not minimizing/maximizing

I am a novice WPF programmer. My problem is as below.
I have a WPF application and on the home screen, when I click on the maximize button, it does not maximize the screen, instead repositions it to the top left column. If I increase/decrease the screen size through click and drag, the maximize button works just fine. The window properties are set up as follows:
<Window x:Class="MyApp.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Uid="Window_Main"
x:Name="HomeWindow"
WindowStyle="None"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
Margin="0"
BorderBrush="Transparent"
BorderThickness="0"
Title="Home"
MinWidth="1000" MinHeight="800"
ResizeMode="CanResizeWithGrip"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SizeToContent="WidthAndHeight"
Visibility="Visible"
d:DesignHeight="1080" d:DesignWidth="1200">
The XAML for button is:
<Button x:Uid="btnRestore" x:Name="btnRestore" Height="20" Width="20" Style="{DynamicResource Control_WindowControlBoxStyle}" Margin="5,0,0,0" ToolTip="Toggle Restore" Click="btnRestore_Click" />
And the code for btnRestore_Click is simple:
private void btnRestore_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Maximized;
}
I am sure there must be some silly mistake that I am committing but not able to figure out what that is. Seems simple but caught me in spin. Any help would be appreciated.
You have SizeToContent="WidthAndHeight", which will make the window resize to whatever size the content in the Window is.
Either remove this property, or make sure first child of your Window tag doesn't have a size set

how to access the grids on silverlight

I have a button called test button an when I click on it I want to show a grid whose visbility is set to 0
I created a mouse button event (below) but my Grid (testGrid) is not available in the project.
private void testButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
testGrid.Opacity = 1;
}
it highlights testGrid red
new to SL so not sure whats going on here
** EDIT **
xml for the Grid
<Grid x:Name="testGrid" HorizontalAlignment="Left" Width="150" Margin="950,-77,0,0" Height="77" VerticalAlignment="Top" Opacity="0">
</Grid>
<Image x:Name="testButton" HorizontalAlignment="Right" Margin="0,1,180,3" Stretch="Fill" Width="53" Height="49" Cursor="Hand" Opacity="0.8" >
The reason that your grid might not be accessibly in the .cs file is if you have changed the class name in the .cs file, but not in the Xaml directive at the top of your .xaml file.
If these two mis match, visual studio won't be able to link up the two files and so you wouldn't be able to see the grid control in the code behind.
Other items with your code to consider:
Though Opacity will work an alternative I use more often is:
This will show the grid.
testGrid.Visibility = Visibility.Visible;
This will hide the grid.
testGrid.Visibility = Visibility.Collapsed;
Also, Your "Button" is an Image tag and not a button. It is an image with the same name as the method you are trying to call. You will either need to change your Image to allow for an on click event or change it to a button, something like
<Button Click="TestBUtton" Text="MyButton" />
And I'd enter that in the Xaml directly so that when you type in the click event handler it auto generates the method in the code behind for you.
try this:
On XAML
<Grid x:Name="testGrid" HorizontalAlignment="Left" Width="150" Margin="950,-77,0,0" Height="77" VerticalAlignment="Top" Opacity="0">
</Grid>
<Image x:Name="testButton" HorizontalAlignment="Right" Margin="0,1,180,3" Stretch="Fill" Width="53" Height="49" Cursor="Hand" Opacity="0.8" MouseLeftButtonDown="testButton" />
on the cs
private void testButton(object sender, System.Windows.Input.MouseButtonEventArgs e){
testGrid.Visibility = Visibility.Visible;
}

Basic WPF Layout question

I am learning WPF and am trying to follow some sort of best practice. I am kind of lost at the moment, and need some direction.
I am creating a very simple app that reads a text file (error log) and splits it into the individual error messages. I want to display these messages (stored in a model object) as a list of messages. Since the list can consist of many items and I want the window to be resizeable, I need a a vertical scroll bar, but I want the content to wrap (i.e. no need for a horizontal scroll bar).
<Window x:Class="ErrorLog.UI.WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="800" Width="1200" Loaded="Window_Loaded">
<StackPanel Name="mainContainer">
<StackPanel Orientation="Horizontal" Name="Menu">
<Button Name="Refresh">Refresh</Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Name="errorMessagePlaceHolder"></StackPanel>
</ScrollViewer>
</StackPanel>
I am at the moment reading the file in the code behind and adding to the stackPanel as a bunch of textboxes with the value being the error message. I have also added some mouseover effects like this:
private void LoadData()
{
IErrorLogReader errorLogReader = new ErrorLogReader();
var errors = errorLogReader.RetrieveErrors();
if (errors.Count == 0)
{
TextBox noErrors = new TextBox();
noErrors.Text = "No errors found";
errorMessagePlaceHolder.Children.Add(noErrors);
}
else
{
for (var i = errors.Count - 1; i > 0; i--)
{
TextBox errorMessage = new TextBox();
errorMessage.IsReadOnly = true;
errorMessage.Padding = new Thickness(10);
errorMessage.Text = errors[i].ErrorMessage;
errorMessage.TextWrapping = TextWrapping.Wrap;
errorMessage.MouseEnter += ErrorMessageMouseEnter;
errorMessage.MouseLeave += ErrorMessageMouseLeave;
errorMessagePlaceHolder.Children.Add(errorMessage);
}
}
}
protected void ErrorMessageMouseEnter(object sender, RoutedEventArgs e)
{
((TextBox) sender).Background = Brushes.AntiqueWhite;
}
protected void ErrorMessageMouseLeave(object sender, RoutedEventArgs e)
{
((TextBox) sender).Background = null;
}
So the first things I want to know is:
Is the way I am binding ok?
Scroll bar is coming up disabled
Is the way I am doing the mouseover effect bad?
Cheers.
Is the way I am binding ok?
It might work, but it's not best practice. Best practice is to use actual data binding. First, you need to replace your StackPanel with something that can be bound to a list. An ItemsControl is the thing closest to a simple StackPanel, other options would be, for example, a ListBox.
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="errorMessageList" />
</ScrollViewer>
private void LoadData()
{
IErrorLogReader errorLogReader = new ErrorLogReader();
var errors = errorLogReader.RetrieveErrors();
errorMessageList.ItemsSource = errors;
}
To specify how you want the error messages to be displayed, you can set a template for the ItemsControl:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="errorMessageList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Scroll bar is coming up disabled
You are nesting your ScrollViewer inside a StackPanel... that won't work: The StackPanel takes as much vertical space as it needs, so the ScrollViewer will always have enough space and never show the scroll bar. You need to replace your top-level StackPanel by something that takes only as much space as is available; a DockPanel, for example:
<DockPanel Name="mainContainer">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Name="Menu">
<Button Name="Refresh">Refresh</Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Name="errorMessagePlaceHolder"></StackPanel>
</ScrollViewer>
</StackPanel>
Is the way I am doing the mouseover effect bad?
That can be done with a style and a trigger instead. Define the following style:
<Window ...>
<Window.Resources>
<Style x:Key="hoverTextBox" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="AntiqueWhite" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
...
</Window>
and assign it to your TextBox inside the DataTemplate:
<TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}"
Style="{StaticResource hoverTextBox}" />

How do I swallow the dropdown behavior inside an Expander.Header?

I would like to prevent an Expander from expanding/collapsing when users click inside the header area. This is basically the same question as Q 1396153, but I'd appreciate a more favorable answer :)
Is there a non-invasive way to do this? I am not sure exactly how to attach behavior to the Expander.Header content to prevent mouseclicks. I'm willing to float in content outside the expander itself via a fixed grid layout, but I'm not keen on the solution. Ideas?
XamlPad sample XAML:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Expander>
<Expander.Header><TextBlock>
When I click this text,
I don't want to trigger expansion/collapse! Only when I click the
expander button do I want to trigger an expand/collapse!
</TextBlock></Expander.Header>
<Grid Background="Red" Height="100" Width="100" >
</Grid>
</Expander>
</Page>
You can stop mouse clicks on the text box from being handled by your application.
XAML:
<Expander>
<Expander.Header>
<TextBlock MouseDown="TextBlock_MouseDown">
When I click this text,
I don't want to trigger expansion/collapse! Only when I click the
expander button do I want to trigger an expand/collapse!
</TextBlock>
</Expander.Header>
<Grid Background="Red" Height="100" Width="100" >
</Grid>
</Expander>
Code behind:
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
I don't know if this is an abomination, but, I've moved the content out of the Expander.Header and done some Grid/fixed layout/Panel.ZIndex trickery to make it appear that the content is in the Expander.Header...but it's not. This works, but it's horrible.

Resources