how to reset the elements in a UserControl shown as popup? - c#

I have a UserControl which is shown in a popup. I have a button in usercontrol that on clicking, makes a textfield visible. But as again i visit that usercontrol, the textfiled remains visible, i want it to be again collapsed until user clicks the button.
I have no clue how to do that? which method to override. please help me

use the UserControl.Loaded event to set your textfield to collapsed.
This blogpost about the Loaded and Initialized Event was very helpful for me.
Example:
UserControl XAML
<UserControl x:Class="YourNamespaceName.YourClassName"
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Loaded="YourClassName_OnLoaded">
<Grid>
<TextBlock x:Name="testTextBlock" Text="Invisible on startup" />
<Button x:Name="testButton" Content="Click" Click="TestButton_OnClick" />
</Grid>
</UserControl>
UserControl CodeBehind
private void YourClassName_OnLoaded(object sender, System.Windows.RoutedEventArgs e)
{
this.testTextBlock.Visibility = Visibility.Collapsed;
}
private void TestButton_OnClick(object sender, RoutedEventArgs e)
{
this.testTextBlock.Visibility = Visibility.Visible;
}

Related

Handled PreviewMouseUp event freezes WPF application

I am listening to the PreviewMouseUp event of a ToggleButton control. Depending on a condition the click event should be raised normally or aborted completely. So the IsChecked property is only set if the condition is true. For this I use the MouseButtonEventArgs.Handled property that is set to false if the condition is false.
If the ToggleButton is clicked and the condition is false the IsChecked property is not set as expected. But the application freezes for no reason. No further button clicks are possible.
If you click into the taskbar (context lost) the application is working again.
MainWindow.xaml
<Window x:Class="ButtonEventTest.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ToggleButton Content="Test Button"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Padding="10"
PreviewMouseUp="UIElement_OnPreviewMouseUp"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void UIElement_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (!IsMouseClickAllowed())
{
e.Handled = true;
}
}
}
Is there something that I am missing? Or is this a known WPF bug?

changing text in parent UserControl from Child UserControl WPF

If a ParentUserControl contains a TextBlock. The ParentUserControlalso contains ChildUserControl that has a TextBox. I want to set the TextBlock of ParentUserControl value from ChildTextBox. how can i ?
In other words somehow accessing the ParentUserControl and it's TextBlock element and then modifying it's value from ChildUserControl !
Update
i have a xaml window that contains a ParentUserControl that has a TextBlock. Now i am loading or adding another ChildUserControl into it on runtime. This newly added ChildUserControl contains a ChildTextBox. Now i want that when i input some value into this ChildTexBox the ParentUserControl's TextBlock should get that value and update itself.
Assuming we are not following any MVVM and a simple approach for this problem is,
Create a ChildUserControl with a textbox inside it as below,
<UserControl x:Class="SO52840402.ChildUserControl"
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SO52607887"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox x:Name="ChildTextBox" />
</Grid> </UserControl>
Create a ParentUserControl which contains a TextBlock and ChildUserControl instance as shown below,
<UserControl x:Class="SO52840402.ParentUserControl"
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SO52607887"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock x:Name="ParentTextBlock" Text="Hallo World!"/>
<local:ChildUserControl x:Name="ChildUserControl" Grid.Row="1" />
</Grid> </UserControl>
Now create a TextChanged event for the TextBox which is under ChildUserControl from code behind of ParentUserControl constructor after "InitializeComponent" as shown below,
public ParentUserControl()
{
InitializeComponent();
ChildUserControl.ChildTextBox.TextChanged += OnChildTextBox_TextChanged;
}
private void OnChildTextBox_TextChanged(object sender, EventArgs e)
{
ParentTextBlock.Text = (sender as TextBox).Text;
}
Note:- This is a not a recommended approach. For best approach, follow MVVM pattern and understand your requirements and do the design. Since you need something from a child user control from a parent user control, a best approach is to have a ViewModel bind to parent and child and access child view model in parent viewmodel and do "what ever you want".

Wpf - popup issue inside Usercontrol when click on button

I have a Window page, after click a button from window page --> then a UserControl page showing. After Inside UserControl there is a <Popup Name="MyPopup"> popup. The Popup always stays on top problem. How can I solve this issue ?
I have tried,
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Background="Green">
<Grid >
<Button Height="50" Width="100" Content="window_ClickMe" Click="btnUserManage_Click"></Button>
<ContentControl Name="cont2" Visibility="Hidden">
</ContentControl>
</Grid>
</Window>
and code behind page of window,
private void btnUserManage_Click(object sender, RoutedEventArgs e)
{
UC_UserMgmt mw = new UC_UserMgmt();
cont2.Content = mw;
cont2.Visibility = Visibility.Visible;
}
then, this is usercontrol page with popup,
<UserControl x:Class="WpfApplication1.UC_UserMgmt"
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Background="Blue">
<Grid>
<Grid Name="g1">
<Button Content="usercontrol_ClickMe" Height="50" Width="150" Margin="150,0,0,250" Click="btnShow_Click"></Button>
</Grid>
<Popup Name="MyPopup" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalOffset="-150" Placement="Mouse" StaysOpen="{Binding ElementName=g1,Path=IsMouseOver}"
VerticalOffset="20"
AllowsTransparency="True">
<StackPanel>
<Border BorderBrush="Black" Background="Brown" BorderThickness="1" Width="300" Height="100" >
<Grid>
<TextBox x:Name="txtUName" HorizontalAlignment="Center" Height="28" Width="223" TextWrapping="Wrap" VerticalAlignment="Top" Margin="10,26,64.6,0" />
<Button Content="Open" Height="30" Width="50" Margin="238,24,9.6,43.6" Click="btnOpen_Click"/>
</Grid>
</Border>
</StackPanel>
</Popup>
</Grid>
</UserControl>
and this is code behind page of usercontrol,
private void btnOpen_Click(object sender, EventArgs e)
{
MyPopup.IsOpen = true;
System.Windows.Forms.OpenFileDialog fDialog = new System.Windows.Forms.OpenFileDialog();
fDialog.Title = "Select file to be zip";
if (fDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtUName.Text = fDialog.FileName.ToString();
}
}
private void btnShow_Click(object sender, EventArgs e)
{
MyPopup.IsOpen = true;
}
The problem is, when user click on OPEN button, an openFileDialog is opening and when it is opened, the popup seems disappear. How can I solve this problem?
I believe using Popup is not the right choice in your situation. Take a look at Popup.StaysOpen Property, in particular the part that says
When the StaysOpen property is set to true, Popup stays open until it is explicitly closed by setting the IsOpen property to false. When StaysOpen is false, the Popup control intercepts all mouse and keyboard events to determine when one of these events occurs outside the Popup control.
I can't think of a clean way of keeping that popup open when showing the dialog box, because the dialog box is going to create a mouse/keyboard event when you interact with it
But to answer your question, I can think of two choices
1) You can simply move MyPopup.IsOpen = true; in btnOpen_Click to the end of the code block. I assume this will cause the popup to reopen after the dialog box is closed
2) You can create a boolean property or dependency property in your code behind set it to true when showing the popup and bind your Popup's StaysOpen to it, and maybe set it to false in LostFocus for g1 or something like that. Or even set StaysOpen to true and use IsOpen to close your Popup in g1's LostFocus
Edit - Second Solution How-To Don't use it, dirty code, bad practices, and the popup remains on top of dialogbox
In the Popup set StaysOpen="True"
In every control in the UserControl except the UserControl itself and the textbox set Focusable="False"
Add private bool dont; to the UserControl's code-behind and set it to True in the beginning of btnOpen_Click and set it to False in its end
In the UserControl and the TextBox add LostFocus="UserControl_LostFocus"
And then add this function in UserControl code-behind
private void UserControl_LostFocus(object sender, RoutedEventArgs e)
{
if(!dont && !txtUName.IsFocused && !IsFocused)
MyPopup.IsOpen = false;
}

AutoResize MainWindow after user resizes window

I have a Window defined as follows:
<Window x:Class="AutomatedSQLMigration.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
SizeToContent="Height"
DataContext="{Binding MainPageViewModel, Source={StaticResource Locator}}">
<DockPanel Name="MasterDockPanel">
...
</DockPanel>
</Window>
I have a number of tabs in a tab control and the window correctly resizes the height to fit the content of the selected tab as long as the user does not change the window size. Once the user changes the window size manually, the window will not resize itself to fit the content of the selected tab.
What can I do to get the window to resize automatically even after the user has manually changed the size?
As far as I know, you required behavior outside the box, so I can see these solutions:
Set the minimum Height for the Window (like this <Window MinHeight="150" ...), in order the user can not change the Height is less than the specified minimum content of TabControl. I think this is the most simple and reliable solution.
Use a hack like this:
XAML
<Window x:Class="AutoResizeProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Loaded="Window_Loaded"
SizeToContent="Height">
<DockPanel Name="MasterDockPanel" Background="Aquamarine">
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Test1">
<TextBlock Name="Test1Content" Background="Red" Height="100">TEST1</TextBlock>
</TabItem>
<TabItem Header="Test2">
<TextBlock>TEST2</TextBlock>
</TabItem>
<TabItem Header="Test3">
<TextBlock>TEST3</TextBlock>
</TabItem>
</TabControl>
</DockPanel>
</Window>
Code-behind
public partial class MainWindow : Window
{
double _initWindowHeight = 0;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_initWindowHeight = this.Height;
}
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_initWindowHeight > 0)
this.Height = _initWindowHeight;
}
}
In this case, you save the initial Height of the Window in Loaded event. Then, when you change tabs (SelectionChanged event) is assigned to the saved value for the Window.

Bringing a user control to the front in Expression Blend, C#, WPF

I have a window with a Grid on.
On this I have some buttons, one of which when clicked will create a new 'PostIt' which is a user control I have created.
What I want to do is click on a 'PostIt' and have that control on top of all the others.
I have tried...
Grid.SetZIndex(sender, value);
Which seems to be the correct code, no errors, just not movement of the control :(
The problem may lie in the fact that the code for the click is in the user control and not the mainwindow cs file. Does this matter?
The 'PostIt' is simply a border with a text box in it.
Are you calling Grid.SetZIndex(sender, value) in a handler of the PostIt mouse click, or a handler for a control inside the PostIt? What is the value that you are setting?
Here is an example that works:
<UserControl x:Class="WpfApplication1.UserControl1"
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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" MouseUp="UserControl_MouseUp">
<Grid>
</Grid>
</UserControl>
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
{
Panel.SetZIndex(this, Panel.GetZIndex(this) + 2);
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 Background="Green" Margin="40,40,100,100" Panel.ZIndex="0" />
<local:UserControl1 Background="Red" Margin="140,140,10,10" Panel.ZIndex="1" />
</Grid>
</Window>
Jogy
This may not be the best solution, but it's the one that worked for me; I was re-ordering two grids:
GridOnBottom.SetValue(Grid.ZIndexProperty, (int)GridOnTop.GetValue(Grid.ZIndexProperty) + 1);
...with GridOnBottom and GridOnTop renamed to the instances of the objects you're re-ordering. Granted, it's not the best solution, but it works.

Categories