How to bind command on entire Grid LeftClick in WPF User Control - c#

I want to achieve Grid Left Click inside a user control.
My WPF User Control
<Grid>
<Border Grid.Row="0" CornerRadius="7" >
<Border.Background>
<SolidColorBrush Color="#ffffff" Opacity="0.08"></SolidColorBrush>
</Border.Background>
<Grid>
<Image Source="/Assets/Images/Icon/ic-add.png" Width="70" Height="70"/>
</Grid>
</Border>
</Grid>
Here is my Window
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<usercontrols:CreateNewProfile Width="200" Height="235" Margin="40,40,0,0">
</usercontrols:CreateNewProfile>
</<StackPanel>
</Grid>
There is a command Called CreateNewProfile
Very straight question How to bind command on Left Click of User Control?

You can use InputBindings inside of your UserControl:
<Grid.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding CreateNewProfile}"/>
</Grid.InputBindings>

Related

Hiding/Showing a UserControl WPF

I am building a WPF MVVM application.
What I have:
I have a ShellWindow which looks like this:
It is composed by 2 rows:
1: the hamburger menu (not important) with Height="*"
2: the console with Height="100"
The console is a UserControl:
<UserControl
//namespaces>
<Grid Name="LoggingGrid" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="{StaticResource SmallLeftMargin}">
<Button
x:Name="CollapseBtn"
Width="25"
Height="25"
Click="CollapseBtn_Click"
Content="▲">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="White" />
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<StackPanel Margin="5,0,0,0" Orientation="Horizontal">
<Image
Height="25"
Source="/Images/console-icon.png"
Visibility="Visible" />
<Label
Content="Console"
FontSize="16"
Foreground="White" />
</StackPanel>
</TextBlock>
<Border Grid.Row="1">
<ListView
x:Name="LoggingList"
Margin="5"
Background="Black"
BorderThickness="0"
Foreground="White"
ItemsSource="{Binding Logs, UpdateSourceTrigger=PropertyChanged}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</Border>
</Grid>
</UserControl>
I have omitted the non-important things.
What I want to do:
Whenever the user clicks on the button, the console should collapse and look something like this:
The arrow is also changed.
How can I implement this? What is the best approach using MVVM?
What I have tried:
I have tried using a button click event handler in the code behind - CollapseBtn_Click, just to see what will happen:
private void CollapseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
{
LoggingGrid.Visibility = System.Windows.Visibility.Hidden;
}
Apparently it removes the user control and leaves a white background where it used to be.
Instead of setting the Visibility of the whole LoggingGrid to Hidden, you should set the Visibility of the LoggingList to Collapsed. (For the difference between Hidden and Collapsed, see here: Difference between Visibility.Collapsed and Visibility.Hidden).
Depending on your layout in the ShellWindow you probably have to adjust your row height configuration in the UserControl such that the collapsed LoggingGrid leads to a row with a height of zero.
Regarding MVVM the best approach would be to bind the Button to a bool property ConsoleVisible on your ViewModel such that clicking the button toggles the property between true and false. The styling of the button can be bound to the same property. For the LoggingList Visibility you could use a Binding with a BooleanToVisibilityConverter on the same property.

How to set Popup panel index that will overlay other controls in WPF?

I have a problem on how to correctly set the Panel.ZIndex of a Popup inside a Grid. The goal is that when I click the Emergency button, a Popup window will display with an image on it and overlay (cover) the buttons (see screenshot below).
I have set the Grid Panel.ZIndex="0"and the Popup to Panel.ZIndex="1" However, the Popup window doesn't overlay the buttons.
This is the XAML implementation.
<StackPanel Background="Black">
<Grid Background="#253341" Panel.ZIndex="0">
<Popup HorizontalOffset="-5" VerticalOffset="0" IsOpen="False"
HorizontalAlignment="Left" VerticalAlignment="Top"
Name="EmergencyPopup" Placement="RelativePoint" AllowsTransparency="True"
PlacementTarget="{Binding ElementName=EmergencyButton}"
Width="1080" Height="1920" Panel.ZIndex="1">
<Border BorderBrush="Black" BorderThickness="2" CornerRadius="2">
<Grid>
<Image Source="{StaticResource EdenParkInfoImg}"/>
<Label FontWeight="Bold" Foreground="Red" HorizontalAlignment="Right" FontSize="25"
MouseLeftButtonDown="Label_MouseLeftButtonDown">close X</Label>
</Grid>
</Border>
</Popup>
</Grid>
</StackPanel>
Screenshot of the Popup window and buttons (the red box indicates that the image inside the Popup is behind the buttons)
Have I correctly set the Panel.ZIndex of the Grid and Popup? What is the correct way of doing it?
Any help is greatly appreciated.
I did find a way on how to solve the issue. In my Popup dialog xaml implementation, I set HorizontalOffset to 0 and VerticalOffset to 180. In that way, Popup dialog vertically overlays the buttons and ZIndex no longer matters. WPFUser is right, it should work without explicitly defining ZIndex.
<Popup HorizontalOffset="0" VerticalOffset="180" IsOpen="False" Width="1080"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="1920"
Name="EmergencyPopup" Placement="Top" AllowsTransparency="True">
<Border BorderBrush="Black">
<Grid>
<Image Source="{StaticResource EdenParkInfoImg}" />
<Label FontWeight="Bold" Foreground="Red" HorizontalAlignment="Right" FontSize="25"
MouseLeftButtonDown="Label_MouseLeftButtonDown" Margin="0,0,15,0">close X
</Label>
</Grid>
</Border>
</Popup>

Popup and StayOpen=False doesnt work with MouseUp

I have a StackPanel with two textblocks. When the StackPanel is clicked, in the code behind I set a Popup to IsOpen=True. I would like this Popup to go away when the user clicks anywhere else in the app that is outside of the Popup.
<DataTemplate DataType="{x:Type something}">
<StackPanel Orientation="Vertical" Margin="3" MouseUp="PanelClick">
<Popup AllowsTransparency="True" PopupAnimation="Slide"
StaysOpen="False">
<Border
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
Padding="4" Opacity="1" CornerRadius="3"
MinHeight="24" MaxWidth="267">
<StackPanel Orientation="Vertical">
<TextBlock Text="Something"/>
<TextBox>aaa</TextBox>
<TextBox>bbb</TextBox>
</StackPanel>
</Border>
</Popup>
<TextBlock
Text="Something else" />
<TextBlock
Text="Some other stuff" />
</StackPanel>
</DataTemplate>
In the code behind I have
private void PanelClick(object sender, MouseButtonEventArgs e)
{
var panel = sender as StackPanel;
var pop = panel?.Children.Cast<Popup>().FirstOrDefault();
if (pop != null)
{
pop.IsOpen = true;
}
}
With the code as presented, I find that the Popup does NOT go away by itself unless I first click (to give focus) into the aaa or bbb textbox and THEN click away from the pop up. It also gives away if I click on a different app. This seems in contradiction to the StaysOpen documentation [https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.popup.staysopen%28v=vs.110%29.aspx]
However, if I put a button around my StackPanel and do the code-behind from the Click event then the Popup works as stated in the documentation
<DataTemplate DataType="{x:Type something}">
<Button Click="ButtonDo">
<StackPanel Orientation="Vertical" Margin="3">
<Popup AllowsTransparency="True" PopupAnimation="Slide"
StaysOpen="False">
<Border
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
Padding="4" Opacity="1" CornerRadius="3"
MinHeight="24" MaxWidth="267">
<StackPanel Orientation="Vertical">
<TextBlock Text="Something"/>
<TextBox>moo</TextBox>
<TextBox>moo</TextBox>
</StackPanel>
</Border>
</Popup>
<TextBlock
Text="Something else" />
<TextBlock
Text="Some other stuff" />
</StackPanel>
</Button>
</DataTemplate>
Why is there this difference of behaviour?
Also, as a curiosity, attempting to use codebehind with MouseUp from the button doesn't even call the code behind - but that's a problem I don't need to know why.

How to make Popup truly modal (similar to MessageDialog)

I am trying to display a popup/modal dialog which includes a textbox or some other additional control. To achieve this, I am setting a UserControl as a child of the Popup. The Popup's width and height are set to full screen so user interaction with ui elements in the background is not possible.
However, I realized that other popups can be displayed over the Popup that I was initially displaying. Thus making this not truly a modal control. Is there a way to make Popup completely modal (block any other UI elements including other Popups). Or is there another control i can use to display some kind of customized message dialog that is modal?
Any help is appreciated, thanks!
You do it like this:
<Grid x:Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Popup x:Name="MyModalPopup" IsOpen="True" IsLightDismissEnabled="False">
<Grid Width="{Binding ActualWidth, ElementName=LayoutRoot, Mode=OneWay}" Height="{Binding ActualHeight, ElementName=LayoutRoot, Mode=OneWay}">
<Grid.Background>
<SolidColorBrush Color="White" Opacity=".25" />
</Grid.Background>
<Grid Width="500" Height="400" Background="Green" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button VerticalAlignment="Center" HorizontalAlignment="Center" Content="Close">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:ChangePropertyAction TargetObject="{Binding ElementName=MyModalPopup}" PropertyName="IsOpen"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
</Grid>
</Popup>
</Grid>
The IsLightDismissEnabled="False" part is important.
Best of luck!

WPF popup staysopen=false still keep the popup open while clicking outside

my problem here is I made a listbox inside the popup, and set the popup's staysopen=false. But each time popup box pops, I have to click something inside the popup(like select an element in listbox), then click outside the popup, and it will close automatically. If I don't click anything, and even if I click other elements outside the popup, the popup stays on. I need the popup closes without needing me to click any element inside it. What can I do? Here is the code, there are some other style link to this code but just some color style.
My control is when user click the textbox on the top of the popup box, the listbox pops. If user does nothing and click any place outside this element, the popup box closes. Thanks.
I can use the following code to get it done in silverlight. But seems like in wpf, it is not working anymore.
popupAncestor = FindHighestAncestor(this.ListBoxPopup);
if (popupAncestor == null)
{
return;
}
popupAncestor.AddHandler(System.Windows.Controls.Primitives.Popup.MouseLeftButtonDownEvent, (MouseButtonEventHandler)ClosePopup, true);
<Grid x:Name="MainGrid" Margin="0" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid Margin="1,1,1,0" x:Name="TopBar" Visibility="Visible" Grid.Row="0" Height="20" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="{StaticResource COL_BTN_LIGHT}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="19"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox x:Name="TextBoxSearchItem" x:FieldModifier="private" HorizontalAlignment="Stretch" Grid.Column="0" VerticalAlignment="Stretch" BorderThickness="0,0,0,0" Background="Transparent" TextChanged="TextBoxSearchItem_TextChanged"></TextBox>
<ToggleButton x:Name="DropDownArrorButton" Grid.Column="1" Style="{StaticResource ComboBoxReadonlyToggleButton}"></ToggleButton>
<!--<TextBlock HorizontalAlignment="Center" Text="Search" Grid.ColumnSpan="2" TextBlock.FontStyle="Italic" Opacity="0.4" VerticalAlignment="Center"/>-->
</Grid>
<Grid Grid.Row="1" HorizontalAlignment="Stretch" x:Name="PopupGrid" Margin="0,1,0,0" >
<Popup x:Name="ListBoxPopup" StaysOpen="False" x:FieldModifier="private" IsOpen="{Binding ElementName=DropDownArrorButton, Path=IsChecked, Mode=TwoWay}"
AllowsTransparency="true" Margin="0" HorizontalAlignment="Stretch" Placement="Bottom"
PlacementTarget="{Binding ElementName=TopBar}" Opened="OnPopupOpened" Closed="OnPopupClosed"
HorizontalOffset="{Binding ElementName=PopupGrid, Path=Value, Mode=TwoWay}"
VerticalOffset="{Binding ElementName=PopupGrid, Path=Value, Mode=TwoWay}">
<ListBox x:Name="ListBoxContainer" Width="{Binding ElementName=MainGrid, Path=ActualWidth}"
HorizontalContentAlignment="Stretch" SelectionMode="Single" Height="200" Margin="0"
SelectionChanged="ListBoxContainer_SelectionChanged"
MouseDoubleClick="ListBoxContainer_MouseDoubleClick">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Border BorderBrush="{Binding SearchedBackColor}" BorderThickness="{Binding Indicator}" Width="{Binding ElementName=MainGrid, Path=ActualWidth}">
<TextBlock x:Name="ContentText" Text="{Binding Name}" Margin="1,0,0,0"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Popup>
<Border x:Name="listBorder" BorderBrush="{StaticResource COL_BTN}" BorderThickness="0,1,0,0" ></Border>
</Grid>
</Grid>
You should create a dependency property in your view model or control for "IsPopupOpen" as shown below to manage state of the popup. Then you can bind both the ToggleButton "IsChecked" and popup "IsOpen" to that DP.
Also on your ToggleButton, set "Focusable=false" and "IsThreeState=false"
public bool IsDropDownOpen
{
get { return (bool)GetValue(IsDropDownOpenProperty); }
set { SetValue(IsDropDownOpenProperty, value); }
}
public static readonly DependencyProperty IsDropDownOpenProperty =
DependencyProperty.Register("IsDropDownOpen", typeof(bool), typeof(Window), new UIPropertyMetadata(false));
Good luck!

Categories

Resources