WPF Main Window is always above other windows - c#

There is much of code. But problem is there:
I've got a Listbox with Control as DataTemplate:
<ListBox x:Name="UpcomingConcertsList" ItemsSource="{Binding UpcomingConcerts}" HorizontalAlignment="Left" Height="350" Margin="10,208,0,0" VerticalAlignment="Top" Width="370">
<ListBox.ItemTemplate>
<DataTemplate>
<Control MouseDoubleClick="UpcomingConcert_DoubleClick">
<Control.Template>
<ControlTemplate>
<Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" CornerRadius="4" Width="320">
<Grid Margin="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" Width="100" Height="75" Margin="6" Source="{Binding ImageURL}"/>
<StackPanel Grid.Column="1" Margin="2,6">
<TextBlock FontWeight="Bold" Text="{Binding Name}"/>
<TextBlock Text="{Binding Date, StringFormat={}{0:g}}"/>
<TextBlock Text="{Binding Bands, Converter={StaticResource BandsConverter}}"/>
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Control.Template>
</Control>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And click event code behind:
private void Concert_DoubleClick(object sender, MouseButtonEventArgs e)
{
Control control = sender as Control;
Concert concert = control.DataContext as Concert;
ConcertView wndw = new ConcertView(concert.ConcertID);
wndw.Show();
}
And ConcertView window is opened but just under my MainWindow. wndw.Activate(), wndw.Focus() don't help.
I tried to do this.IsEnabled = false and wndw.Show() after this. Then my ConcertView was above MainWindow. But as this.IsEnabled comes to true, ConcertView suddenly goes under.
Is ther eany ideas?

But TopMost makes my window being over all the applications What do you mean by this? You're currently using an application and when you click a button, a new window is loaded. So you want the new window to be at topmost itself right?
You can set the Owner property of a window to set it's owner. ie the MainWindow. If you set this then the current window will be owner window.
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
Now try setting the wndw.TopMost = true;and check if its working.

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.

Get UserControls dynamically via XamlReader.Load, IsLoaded is false at UI Elements

I try to save and load TabItems via XamlWriter and XamlReader at runtime so that the user can restore the previous session. Each TabItem consists of UserControls and standard WPF controls like grids,buttons and checkboxes.
It all works fine until I try to subscribe to events of let's say a button.
If I raise them manually with RaiseEvent() they work, but if I click on them nothing happens. Even if I set IsEnabled=false the button is displayed as enabled. LogicalTreeHelper.FindLogicalNode gives me the right button, but the Click event also won't trigger. The IsLoaded property is false, so I assume there has to be some underlying problem with the initialization.
Basically this is the code to read from the file
StreamReader sw = new StreamReader(file);
XmlReader xmlReader = XmlReader.Create(sw);
TabItem tabItem = (TabItem)XamlReader.Load(xmlReader);
.. and this to save each TabItem to a seperate xml file
foreach (TabItem tabItem in tabControlMain.Items)
{
StreamWriter sw = new StreamWriter(Path.Combine(path,tabItem.Name + ".xml"), false);
string savedTab = XamlWriter.Save(tabItem);
sw.Write(savedTab);
sw.Close();
}
Here is an example TabItem saved to a file
<TabItem IsSelected="True" Header="Test" Name="tabItem1" HorizontalAlignment="Left" VerticalAlignment="Top" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:womoc="clr-namespace:WeldOsMqttOpcClient;assembly=blabla">
<TabItem.HeaderTemplate>
<DataTemplate DataType="{x:Type TabItem}">
<TextBox Margin="0,0,30,0" Text="{Binding Path=.}" />
</DataTemplate>
</TabItem.HeaderTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<womoc:UcOverviewTabPage Autoconnect="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Name="gridParentOv">
<Grid Name="gridMqttOpcControls" Height="599.08" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<womoc:UcConnection Name="ucOpc" MinWidth="400" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<GroupBox Header="OPC [10.5.51.130]" Name="groupBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer>
<Grid Name="gridTextBoxesWithValues" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Name="rowLabel" />
</Grid.RowDefinitions>
<Label Background="#FF008000" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelConnected" Width="190" Height="26" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.ColumnSpan="2">Connected!</Label>
</Grid>
</ScrollViewer>
</GroupBox>
</womoc:UcConnection>
</Grid>
<Grid Name="gridConnection" MinHeight="30" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Button Name="btnConnect" Width="55" Margin="100,0,0,10" HorizontalAlignment="Center" VerticalAlignment="Bottom" IsEnabled="False">Connect</Button>
<TextBox Name="tbIPAddress" Width="95" Height="18" Margin="0,0,100,10" HorizontalAlignment="Center" VerticalAlignment="Bottom" IsEnabled="False">10.5.51.130</TextBox>
<CheckBox Name="cbMqtt" Width="46" Height="15" Margin="20,0,0,10" HorizontalAlignment="Left" VerticalAlignment="Bottom" IsEnabled="False">Mqtt</CheckBox>
<CheckBox IsChecked="True" Name="cbOpc" Width="42" Margin="0,0,20,10" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsEnabled="False">Opc</CheckBox>
</Grid>
</Grid>
</womoc:UcOverviewTabPage>
</Grid>
</TabItem>
UcOverviewTabPage is one of my UserControls, in which there is for example a button. I try to subscribe to the events manually ->
public UcOverviewTabPage()
{
InitializeComponent();
cbMqtt.Checked += CbMqtt_Checked;
cbMqtt.Unchecked += CbMqtt_Unchecked;
cbOpc.Checked += CbOpc_Checked;
cbOpc.Unchecked += CbOpc_Unchecked;
btnConnect.Click += BtnConnect_Click;
var children = LogicalTreeHelper.FindLogicalNode(this, "btnConnect") as Button;
bool loaded = children.IsLoaded;
// -> FALSE
}
Bear in mind, creating new custom UserControls during runtime works perfectly. The problem only occurs when reading out of the XML file.
I except the UserControls or any other Controls to work like they do when created during runtime. What am I missing?

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.

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!

My window doesn't display when I call .Show()

I have this window defined in C#:
<Window x:Class="VirginOneAccount.AccountInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Account Information" Height="362" Width="614" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="AccountTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AccountName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="418*" />
<ColumnDefinition Width="174*" />
</Grid.ColumnDefinitions>
<ComboBox Height="23" HorizontalAlignment="Stretch" Margin="40,16,42,0" Name="AccountsList" VerticalAlignment="Top" Width="Auto" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}" ItemTemplate="{StaticResource AccountTemplate}" AllowDrop="False" DataContext="{Binding}" IsEnabled="True" SelectionChanged="AccountsList_SelectionChanged" />
<Button Content="Save Changes" Height="23" HorizontalAlignment="Left" Margin="40,0,0,10" Name="saveChanges" VerticalAlignment="Bottom" Width="90" IsEnabled="False" Click="saveChanges_Click" />
</Grid>
Then in the main form, I call Show() on an instance of the window:
AccountInfo Accounts = new AccountInfo();
Accounts.Show();
But all I see is an empty window (not even the right size). Why isn't it opening my window?
I did a simple window and this worked for me. Take it down to just a textbox and see if it works.
public MainWindow()
{
InitializeComponent();
Window1 win1 = new Window1();
win1.Show();
}
The window class name may be different between the xaml definition and the code behind file.
Example
telerik:RadWindow x:Class="MyWindow"
vs
public partial class My_Window : RadWindow
{
public My_Window()
{
InitializeComponent();
}
}
In this case the initializeComponent() call is unrecognized by the compiler

Categories

Resources