xaml
<Window x:Class="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">
<StackPanel VerticalAlignment="Center" Width="300">
<PasswordBox x:Name="PasswordBox1" Height="30" PasswordChar="*" Password="12345"/>
<CheckBox x:Name="CheckBox1" Content="Show Password"/>
</StackPanel>
</Window>
vb.net
Class MainWindow
Private Sub CheckBox1_Checked(sender As Object, e As RoutedEventArgs) Handles CheckBox1.Checked
PasswordBox1.PasswordChar = CChar("")
End Sub
Private Sub CheckBox1_Unchecked(sender As Object, e As RoutedEventArgs) Handles CheckBox1.Unchecked
PasswordBox1.PasswordChar = CChar("*")
End Sub
End Class
Run the above codes and click CheckBox1 in order to understand what is happening.
How can PasswordBox show characters which are 12345 when I click CheckBox?
So, following line need to be repaired.
PasswordBox1.PasswordChar = CChar(" ")
This will work for what you are looking for although it will expose your passwords in memory. We have a textbox and a password box in the same place on our UI and when the user checks the Show Password checkbox we collapse the passwordbox and show the hidden textbox, at the same time updating the text. You will need to check you are using the password from the visible ui control when you send the password.
Xaml code:
<StackPanel Orientation="Horizontal">
<Grid Width="300" Height="40">
<PasswordBox Name="passwordBox" PasswordChar="*" />
<TextBox Name="passwordTxtBox" Visibility="Collapsed" />
</Grid>
<CheckBox Margin="10" Name="showPassword" Unchecked="ShowPassword_Unchecked" Checked="ShowPassword_Checked" />
</StackPanel>
Code behind:
private void ShowPassword_Checked(object sender, RoutedEventArgs e)
{
passwordTxtBox.Text = passwordBox.Password;
passwordBox.Visibility = Visibility.Collapsed;
passwordTxtBox.Visibility = Visibility.Visible;
}
private void ShowPassword_Unchecked(object sender, RoutedEventArgs e)
{
passwordBox.Password = passwordTxtBox.Text;
passwordTxtBox.Visibility = Visibility.Collapsed;
passwordBox.Visibility = Visibility.Visible;
}
I recommend Using MahApps.Metro ... after installing it from nuget.org ... you must import it in the head of your xaml like this xmlns:controls="http://metro.mahapps.com/winf/xaml/controls"
and then ... just use it's style for your PasswordBox control
<PasswordBox Style="{StaticResource MetroButtonRevealedPasswordBox}" />
you can even change the content for the show icon using the controls:PasswordBoxHelper.RevealButtonContent attached property
Related
Sorry about the headline but it was the best I could come up with. Let me explain my problem: I have a WPF application that has a Menu looking much like your standard top menu that only takes up 5% of the screen. Click a menu item and the view below changes. The menu control is home-brewed because of reasons: Dynamic changes to menu-items, weird UI that doesn't fit existing controls, etc.
The menu changing view part is done using a ContentControl that binds to a "CurrentMenuView" property. When a menu item is clicked, this happens (pseudo-code):
private async void Button_Pressed(...)
{
await MakeSomeVisualMenuChanges();
CurrentMenuView = new CarsView();
await MakeSomOtherStuff();
}
The problem is that some views take some time to load, which makes the other steps happen slow also. I'd like to start loading the "CarsView" but at the same time (not after) continue with the other changes. So the user can see stuff happening.
I can solve this by using Task.Run() but that seems wrong as it puts stuff in a different context.
What is the correct / better way of dealing with this?
EDIT:
Thanks for all answers, as I expected this is not easy to explain. Let me try with a simple example:
MainWindows.xaml:
<Window x:Class="WpfApp32.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 ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="300" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Width="50" Content="Click" Click="Button_Click" />
<ContentControl Grid.Row="1" Width="200" Height="200" Content="{Binding PageContent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Text="Bottom" Width="300" x:Name="BottomText" />
</Grid>
</Window>
Code-Behind:
using System.Windows;
using System.ComponentModel;
namespace WpfApp32
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
BottomText.Text = "AndNowforSomethingCompletelyDifferent";
PageContent = new UserControl1();
}
private object pageContent;
public object PageContent
{
get => pageContent;
set
{
pageContent = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PageContent)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
UserControl1.xaml:
<UserControl x:Class="WpfApp32.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"
Loaded="UserControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock x:Name="CtrlTextBlock" Width="100"/>
</Grid>
</UserControl>
UserControl1.cs:
using System.Windows;
using System.Windows.Controls;
namespace WpfApp32
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void Init()
{
System.Threading.Thread.Sleep(2000);
CtrlTextBlock.Text = "Loaded";
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Init();
}
}
}
So this is stripped from async etc and just showing the issue. When the button is pressed, the UserControl1 is loaded but it takes 2 seconds to load. Until then, the text in the "BottomText" element remains unset.
As I said before, I can solve this by doing something like this in the button click:
private void Button_Click(object sender, RoutedEventArgs e)
{
BottomText.Text = "AndNowforSomethingCompletelyDifferent";
System.Threading.Tasks.Task.Run(() => Application.Current.Dispatcher.Invoke(() => PageContent = new UserControl1()));
}
But not sure that is the way to go. So the basic issue here, is that a ContentControl is bound to a property and setting that property might take some time. While that is loading I don't want execution in the MainWindow to be halted (I want the BottomText element to display "AndNowforSomethingCompletelyDifferent" immediately).
Here's an example that simulates 3 seconds of loading... It's not an extremely complex UI and binding to complex DataTemplates, especially nested, can slow things a bit but normally the drag comes from pulling the data.
The trick is having a clever UI that keeps things moving but also lets the user know it's waiting on something else to continue. The infamous loading bar for example... Not that I would use that exact process but that's the right idea.
Note and disclaimer: I almost despise code behind unless it's in a custom control of some type; never in the view. I always prefer MVVM and using a ViewModel for binding; but not to build or control the UI only for the data the UI uses. All that said because this example is none of that. I simply made the controls on the view and put the code behind for answering this question, with example, as simple as possible.
The View
<Window x:Class="Question_Answer_WPF_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="500"
Width="800">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<ToggleButton x:Name="menuButton"
Content="Menu"
Click="MenuButton_Click" />
<!--I do not recommend binding in the view like this... Make a custom control that does this properly.-->
<Grid x:Name="menu"
Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=menuButton}"
VerticalAlignment="Top"
Grid.Row="1"
Background="Wheat">
<StackPanel x:Name="menuItems">
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
<TextBlock Text="simulated...." />
</StackPanel>
<StackPanel Name="menuLoading">
<TextBlock Text="Loading..."
FontSize="21" />
<ProgressBar IsIndeterminate="True"
Height="3" />
</StackPanel>
</Grid>
</Grid>
</Window>
Code Behind the View
using System.Threading.Tasks;
using System.Windows;
namespace Question_Answer_WPF_App
{
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
private Task SimulateLoadingResourcesAsnyc() => Task.Delay(3000);
private async void MenuButton_Click(object sender, RoutedEventArgs e)
{
menuItems.Visibility = Visibility.Collapsed;
menuLoading.Visibility = Visibility.Visible;
await SimulateLoadingResourcesAsnyc();
menuItems.Visibility = Visibility.Visible;
menuLoading.Visibility = Visibility.Collapsed;
}
}
}
I have been fixating on this from some time:
I am developing a windows phone app:
I have a XAML Page as a template and three UserControls:
One of which has map-layout, one generalInfo-layout, Summary+Pic layout.
I want to create 3 buttons at the top and change the active UserControl respectively.
I dont want to you use a PivotPage.
HELP? Advice? Code?
One very primitive approach would be to subscribe to the Click event of all 3 buttons and basically just change the Visibility property of your UserControls in the event handlers appropriately.
Of course there are other approaches you might want to consider - like using the MVVM pattern or using TabControl and TabItem from the sdk if available for WP7 or using event triggers - but this can be a good starting point.
Your MainPage should look something like this:
<UserControl x:Class="SilverlightApplication10.MainPage"
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"
xmlns:silverlightApplication10="clr-namespace:SilverlightApplication10"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel x:Name="LayoutRoot"
Orientation="Horizontal"
Background="White">
<Button Height="30"
Content="content1"
Click="Button_Click" />
<Button Height="30"
Content="content2"
Click="Button_Click_1" />
<Button Height="30"
Content="content3"
Click="Button_Click_2" />
</StackPanel>
<Grid Grid.Row="1">
<silverlightApplication10:SilverlightControl1 x:Name="ctrl1"
Visibility="Collapsed" />
<silverlightApplication10:SilverlightControl2 x:Name="ctrl2"
Visibility="Collapsed" />
<silverlightApplication10:SilverlightControl3 x:Name="ctrl3"
Visibility="Collapsed" />
</Grid>
</Grid>
</UserControl>
And then your event handlers should take care of setting the Visibility property of all these UserControls:
private void Button_Click(object sender, RoutedEventArgs e)
{
ctrl1.Visibility = Visibility.Visible;
ctrl2.Visibility = Visibility.Collapsed;
ctrl3.Visibility = Visibility.Collapsed;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
ctrl2.Visibility = Visibility.Visible;
ctrl1.Visibility = Visibility.Collapsed;
ctrl3.Visibility = Visibility.Collapsed;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
ctrl3.Visibility = Visibility.Visible;
ctrl1.Visibility = Visibility.Collapsed;
ctrl2.Visibility = Visibility.Collapsed;
}
I have a page containing two StackPanels, each containing one TextBox and one Button:
<StackPanel x:Name="Row1">
<TextBox x:Name="TextBox1" Text="" GotFocus="OnFocusHandler" LostFocus="OffFocusHandler"/>
<Button x:Name="Button1" Content="Convert" Click="OnClickHandler" Visibility="Collapsed"/>
</StackPanel>
<StackPanel x:Name="Row2">
<TextBox x:Name="TextBox2" Text="" GotFocus="OnFocusHandler" LostFocus="OffFocusHandler"/>
<Button x:Name="Button2" Content="Convert" Click="OnClickHandler" Visibility="Collapsed"/>
</StackPanel>
I would like to do the following:
When a textbox has focus, the other textbox must be hidden and the corresponding button must show
When a textbox is out of focus, we are back to the original display: only empty textboxes are visible
I don't want the button to be able to trigger the OffFocusHandler
This is the current code that I have for the three handlers:
private void OnFocusHandler(object sender, RoutedEventArgs e)
{
TextBox SenderTextBox = (TextBox)sender;
if (SenderPanel.Name == "TextBox1")
{
Button1.Visibility = Visibility.Visible;
}
else if (SenderPanel.Name == "TextBox2")
{
Button2.Visibility = Visibility.Visible;
}
}
private void OffFocusHandler(object sender, RoutedEventArgs e)
{
TextBox1.Text = "";
TextBox2.Text = "";
Button1.Visibility = Visibility.Collapsed;
Button2.Visibility = Visibility.Collapsed;
}
private void OnClickHandler(object sender, RoutedEventArgs e)
{
// some stuff unrelated to my issue
}
How do I avoid the button clicking to trigger the OffFocusHandler code?
Is there another way to code this? I'm a complete beginner so I may not think the right way.
You can just Bind to the TextBox.IsFocused property in Xaml, and use the BooleanToVisibilityConverter to show/hide the button.
Example:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="300" Width="400" Name="UI" >
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolTovisible" />
</Window.Resources>
<Grid>
<StackPanel x:Name="Row1" Height="54" VerticalAlignment="Top">
<TextBox x:Name="TextBox1" Text="" />
<Button x:Name="Button1" Content="Convert" Visibility="{Binding ElementName=TextBox1, Path=IsFocused, Converter={StaticResource BoolTovisible}}"/>
</StackPanel>
<StackPanel x:Name="Row2" Margin="0,60,0,0" Height="51" VerticalAlignment="Top">
<TextBox x:Name="TextBox2" Text="" />
<Button x:Name="Button2" Content="Convert" Visibility="{Binding ElementName=TextBox2, Path=IsFocused, Converter={StaticResource BoolTovisible}}"/>
</StackPanel>
</Grid>
</Window>
for each element, there is a Visibility tag, it is "Visible" by default but you can assign "Hidden" or "Collapsed" as follow:
<RadioButton Margin="20,118,318,-43" GroupName="MCSites" Visibility="Hidden">
Radio Button Description
</RadioButton>
I am new to WPF and I want to create a WPF application with 5buttons. On the click of each button I want a content to be displayed on another panel. Right now I just want different images to be displayed on my right side panel on the button clicks.
Here's my XAML code:
<Window x:Class="GridButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyFirstApp" Height="350" Width="525" Loaded="Window_Loaded">
<Viewbox Stretch="Fill" StretchDirection="Both">
<DockPanel>
<StackPanel DockPanel.Dock="left" Margin="5" Width="Auto" VerticalAlignment="Center" Height="Auto">
<Button Content="1" Name="button2" Click="button2_Click">
</Button>
<Button Content="2" Name="button1" Click="button1_Click_1">
</Button>
<Button Content="3" Name="button3" Click="button3_Click">
</Button>
<Button Content="4" Name="button4" Margin="5">
</Button>
<Button Content="5" Name="button5" Margin="5" Click="button5_Click_1">
</Button>
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Image Name="img1" Source="Blue Hills.jpg" Stretch="Uniform" Visibility="Hidden" ImageFailed="Image_ImageFailed" Height="257" />
</StackPanel>
</DockPanel>
And my xaml.cs file contains code to display image:
private void button2_Click(object sender, RoutedEventArgs e)
{
img1.Visibility = Visibility.Visible;
}
I could get only this far.
You can set the Source property of the Image control in code:
private void buttonx_Click(object sender, RoutedEventArgs e)
{
string path = ... // path to image file here
img1.Source = new BitmapImage(new Uri(path));
}
You could easily reuse the same Click handler for all Buttons and check which one was pressed:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
string path = null;
if (button == button1)
{
path = ... // path to image file 1 here
}
else if ...
if (path != null)
{
img1.Source = new BitmapImage(new Uri(path));
}
}
If you want to remove the a child Panel (or other control) from a parent Panel and add another one, you would have to modify the Panel's Children property:
<StackPanel Name="parent">
<StackPanel Name="child" />
</StackPanel>
parent.Children.Remove(child);
parent.Children.Add(...); // some other control here
This approach would usually make sense if you wanted to create child panels dynamically. If you want to declare everything in XAML you may put all child panels in a Grid and change their visibility as you did already.
However, you might also change the ZIndex attached property.
<Grid>
<StackPanel Name="child1">
</StackPanel>
<StackPanel Name="child2">
</StackPanel>
<StackPanel Name="child3">
</StackPanel>
</Grid>
child3 is topmost by default, but now you can set ZIndex to some value > 0 to make another child topmost:
private void Button_Click(object sender, RoutedEventArgs e)
{
...
// reset ZIndex on previous topmost panel to 0 before
Panel.SetZIndex(child1, 1);
}
Or completely omit the Button/Grid/Panel design and use a TabControl.
This is the required behaviour:
I have various controls present on the canvas e.g. Callouts (from Expression Blend .dll), or simple Labels. When the user 'double clicks' (or any other event I decide to tie in) the control should change its appearance to allow the user to edit the control's Content property. Clicking off the control should then turn it back to 'read-only' method.
Any suggestions on how this would be best achieved? Ideally I want to do this all in c# to add this behaviour to the control at runtime (as this control is added dynamically to the canvas)- and avoid XAML altogether.
I reckon I've got to do something with adorners to display a textbox bound to the control's content property on the required event, but some code samples or links elsewhere would be appreciated? :) - I haven't been able to find anything on an existing search, but I reckon it should be fairly simple.
Unfortunately, style triggers do not do anything with IsReadOnly and IsEnabled. You would have to do that from an event.
Here is my sample:
WPF:
<Window x:Class="StateChangingTextbox.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">
<Window.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#eee" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Width="300" Height="200" TextWrapping="Wrap" IsReadOnly="True"
MouseEnter="TextBox_MouseEnter"
MouseLeave="TextBox_MouseLeave"/>
</Grid>
</Window>
Code-behind:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void TextBox_MouseEnter(object sender, MouseEventArgs e)
{
var textbox = sender as TextBox;
if (textbox != null)
{
textbox.IsReadOnly = false;
}
}
private void TextBox_MouseLeave(object sender, MouseEventArgs e)
{
var textbox = sender as TextBox;
if (textbox != null)
{
textbox.IsReadOnly = true;
}
}
}
XAML:
<UserControl
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"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="ComicWPF.Bubble"
x:Name="UserControl" Height="100" Width="200">
<Canvas LostFocus="this_LostFocus">
<ed:Callout x:Name="callout" Content=""
AnchorPoint="0,1" FontSize="14" Height="100" Width="200"
Fill="Blue"
PreviewMouseDoubleClick="Callout_DoubleClick"
Canvas.Left="0" Canvas.Top="0" />
<TextBox x:Name="textbox"
FontSize="14"
Canvas.Left="30" Height="55" Width="80" Canvas.Top="30"
Visibility="Visible"/>
</Canvas>
</UserControl>
C# Code:
private void Callout_DoubleClick(object sender, MouseButtonEventArgs e)
{
Activate();
}
public void Activate()
{
//set bool activated to true
//make textbox visible and set focus and select all text
}
private void Callout_DeSelect()
{
//set content of callout to the textbox.Text
//Hide textbox
//set bool activated to false
}
private void this_LostFocus(object sender, RoutedEventArgs e)
{
Callout_DeSelect();
}
}