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

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.

Related

Popup and Window's AllowsTransparency

As soon as I set AllowsTransparency to true in a Window and close a Popup in front of this Window, the Window is not redrawn and the popup still shows up on top of the Window.
If this Window lose focus or If I enter the "alt" key of the keyboard, the Window is redrawn and displays correctly.
To be more clear:
Without AllowTransparency
Popup shown:
Popup hidden:
With AllowTransparency
Popup shown:
Popup hidden:
XAML:
<Window x:Class="Tests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="1000"
WindowStyle="None"
AllowsTransparency="True">
<Grid>
<Rectangle Width="1000" Height="300" Fill="Red"></Rectangle>
<CheckBox x:Name="PopupCheckBox">
<TextBlock Text="Show popup"/>
</CheckBox>
<Popup IsOpen="{Binding ElementName=PopupCheckBox, Path=IsChecked}" Placement="Center">
<Rectangle Width="500" Height="500" Fill="Green" />
</Popup>
</Grid>
</Window>
I would like to know what is the cause of this behavior and how to fix/bypass it.
Thank you.
Edit
I tried to call InvalidateVisual in the handler of the popup's Closed event but it did not change the behavior:
public MainWindow()
{
InitializeComponent();
PopupTest.Closed += PopupTest_Closed;
}
void PopupTest_Closed(object sender, EventArgs e)
{
InvalidateVisual();
}
Edit 2
Ok so it appear that the graphic card driver is the cause of this behavior. I updated it to the latest one and while an artifact is still shown, it behaves differently (shown area of the popup is much smaller).
Closing this thread. Thanks to all.
As stated in the question's latest edit, the artifact is caused by outdated graphic card driver.
I can't tell you the cause but to fix this issue use the method InvalidateVisual on your window when closing the popup.
window.InvalidateVisual();

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

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;
}

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;
}

Silverlight MouseLeave showing inconistent behaviour

So, my problem is that the MouseLeave event only gets triggered if I move my cursor at a certain speed. Below is a Thumb with a Border. Click the thumb and keep the mouse button down. Move slowly outside the border = no event, Move fast outside the border = event.
<Grid x:Name="LayoutRoot" Background="White">
<Border BorderBrush="Black" BorderThickness="3" Width="200" Height="100"
MouseLeave="Border_MouseLeave">
<Thumb />
</Border>
</Grid>
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
MessageBox.Show("Border_MouseLeave");
}
Is it a bug in silverlight or am I missing something?
Thanx
/Mike
Thanx for the anwers, here's an update:
It seems to have something to do with MouseCapture as Guy suggests. The reason being that I also get the problem using Button or a Rectangle that captures the mouse in code-behind.
If I put a Grid between the Thumb and the Border the problem disappears so I think I will go with that.
I also noticed a related problem as I played around some.
<Grid Width="200" Height="100" Background="Transparent"
MouseLeave="Border_MouseLeave">
<Button />
<Rectangle Width="40" Height="40" Fill="Violet"
HorizontalAlignment="Left" />
</Grid>
If I press the left button and move the cursor to the left over the Rectangle and out the MouseLeave event is not registered.
This is all very strange.

Size-to-content-layout problem in WPF

This is supposed to be a no brainer but I still can’t figure it out.
In my sample app there’s a button and a textbox in a dockpanel. If the content of the textbox is smaller than the content of the textbox the window is as big as it needs to be to display the content of the button. That’s what I want. But if I put more text into the textbox the window gets wider :-(
The behavior I want is that the window gets the width according to the buttons content and the textbox wraps its content (or/and shows scrollbars if necessary).
Thank you!
Some sample code:
<Window x:Class="SO1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" SizeToContent="Width" FontSize="20">
<DockPanel>
<Button DockPanel.Dock="Top">A rather long text</Button>
<TextBlock TextWrapping="Wrap">Short text</TextBlock>
</DockPanel>
</Window>
Having tried it, it seems that binding the TextBlock's MaxWidth to the ActualWidth of the Button achieves the effect you're after:
<Button x:Name="btn" DockPanel.Dock="Top">Short text</Button>
<TextBlock TextWrapping="Wrap"
MaxWidth="{Binding ElementName=btn,Path=ActualWidth}">A rather long text</TextBlock>

Resources