Skip to content

Commit

Permalink
#6: use PasswordBox instead of TextBox for password
Browse files Browse the repository at this point in the history
  • Loading branch information
meancrazy committed Feb 22, 2016
1 parent 09d668b commit 15bee63
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 150 deletions.
1 change: 1 addition & 0 deletions LINQPadOData4.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<Compile Include="Extensions.cs" />
<Compile Include="OData4DynamicDriver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\PasswordBehavior.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
Expand Down
155 changes: 80 additions & 75 deletions UI/ConnectionDialog.xaml
Original file line number Diff line number Diff line change
@@ -1,75 +1,80 @@
<Window x:Class="OData4.UI.ConnectionDialog"
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"
xmlns:ui="clr-namespace:OData4.UI"
Title="OData 4"
Width="450"
WindowStartupLocation="CenterScreen"
SizeToContent="Height"
ResizeMode="NoResize"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
d:DataContext="{d:DesignInstance Type=ui:ConnectionProperties, IsDesignTimeCreatable=True}">
<StackPanel Orientation="Vertical" Margin="4" >
<Label Margin="0 0 0 4">_URI</Label>
<TextBox Margin="0 0 0 4" Text="{Binding Uri}" Height="20" TabIndex="0"></TextBox>
<GroupBox Header="Log on details" Margin="0 0 0 4" Padding="4">
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<ui:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</StackPanel.Resources>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.None}}" TabIndex="1">_No authentication</RadioButton>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.Windows}}" TabIndex="2">_Windows authentication</RadioButton>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.Basic}}" TabIndex="3" Name="BasicAuthentication">_Basic authentication</RadioButton>
<Grid Margin="40 4 100 4">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=BasicAuthentication}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0">_User name</Label>
<TextBox Grid.Column="1" Grid.Row="0" Height="20" TabIndex="4" Text="{Binding UserName}"></TextBox>
<Label Grid.Column="0" Grid.Row="1">_Password</Label>
<TextBox Grid.Column="1" Grid.Row="1" Height="20" TabIndex="5" Text="{Binding Password}"></TextBox>
<Label Grid.Column="0" Grid.Row="2">_Domain (optional)</Label>
<TextBox Grid.Column="1" Grid.Row="2" Height="20" TabIndex="5" Text="{Binding Domain}"></TextBox>
</Grid>
</StackPanel>
</GroupBox>
<CheckBox Margin="0 0 0 4" TabIndex="6" IsChecked="{Binding Persist}">_Remember this connection</CheckBox>
<Expander Header="_Advanced" Margin="0 0 0 4" TabIndex="7">
<StackPanel Margin="50 0 0 0">
<CheckBox TabIndex="8" IsChecked="{Binding UseProxy}">Use LINQPad web proxy</CheckBox>
<Label TabIndex="9">
<Hyperlink Click="WebProxySetup">Web Proxy Setup...</Hyperlink>
</Label>
</StackPanel>
</Expander>
<DockPanel Margin="0 10 0 0" LastChildFill="False" HorizontalAlignment="Right">
<DockPanel.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="4 0 0 0" />
<Setter Property="MinWidth" Value="60" />
</Style>
</DockPanel.Resources>
<Button IsDefault="True" TabIndex="10" Click="OnOkClick">_OK</Button>
<Button IsCancel="True" TabIndex="11">_Cancel</Button>
</DockPanel>
</StackPanel>
</Window>

<Window x:Class="OData4.UI.ConnectionDialog"
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"
xmlns:ui="clr-namespace:OData4.UI"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="OData 4"
Width="450"
WindowStartupLocation="CenterScreen"
SizeToContent="Height"
ResizeMode="NoResize"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
d:DataContext="{d:DesignInstance Type=ui:ConnectionProperties, IsDesignTimeCreatable=True}">
<StackPanel Orientation="Vertical" Margin="4" >
<Label Margin="0 0 0 4">_URI</Label>
<TextBox Margin="0 0 0 4" Text="{Binding Uri}" Height="20" TabIndex="0"></TextBox>
<GroupBox Header="Log on details" Margin="0 0 0 4" Padding="4">
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<ui:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</StackPanel.Resources>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.None}}" TabIndex="1">_No authentication</RadioButton>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.Windows}}" TabIndex="2">_Windows authentication</RadioButton>
<RadioButton Margin="0 0 0 4" IsChecked="{Binding Path=AuthenticationType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static ui:AuthenticationType.Basic}}" TabIndex="3" Name="BasicAuthentication">_Basic authentication</RadioButton>
<Grid Margin="40 4 100 4">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=BasicAuthentication}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0">_User name</Label>
<TextBox Grid.Column="1" Grid.Row="0" Height="20" TabIndex="4" Text="{Binding UserName}"></TextBox>
<Label Grid.Column="0" Grid.Row="1">_Password</Label>
<PasswordBox Grid.Column="1" Grid.Row="1" Height="20" TabIndex="5" >
<i:Interaction.Behaviors>
<ui:PasswordBehavior Password="{Binding Password, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</PasswordBox>
<Label Grid.Column="0" Grid.Row="2">_Domain (optional)</Label>
<TextBox Grid.Column="1" Grid.Row="2" Height="20" TabIndex="5" Text="{Binding Domain}"></TextBox>
</Grid>
</StackPanel>
</GroupBox>
<CheckBox Margin="0 0 0 4" TabIndex="6" IsChecked="{Binding Persist}">_Remember this connection</CheckBox>
<Expander Header="_Advanced" Margin="0 0 0 4" TabIndex="7">
<StackPanel Margin="50 0 0 0">
<CheckBox TabIndex="8" IsChecked="{Binding UseProxy}">Use LINQPad web proxy</CheckBox>
<Label TabIndex="9">
<Hyperlink Click="WebProxySetup">Web Proxy Setup...</Hyperlink>
</Label>
</StackPanel>
</Expander>
<DockPanel Margin="0 10 0 0" LastChildFill="False" HorizontalAlignment="Right">
<DockPanel.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="4 0 0 0" />
<Setter Property="MinWidth" Value="60" />
</Style>
</DockPanel.Resources>
<Button IsDefault="True" TabIndex="10" Click="OnOkClick">_OK</Button>
<Button IsCancel="True" TabIndex="11">_Cancel</Button>
</DockPanel>
</StackPanel>
</Window>

150 changes: 75 additions & 75 deletions UI/ConnectionDialog.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using LINQPad.Extensibility.DataContext;
using MessageBox = System.Windows.MessageBox;

namespace OData4.UI
{
public partial class ConnectionDialog
{
public ConnectionDialog(IConnectionInfo cxInfo)
{
InitializeComponent();
DataContext = new ConnectionProperties(cxInfo);
}

/// <summary>
/// Raises the <see cref="E:System.Windows.Window.SourceInitialized"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnSourceInitialized(EventArgs e)
{
IntPtr hwnd = new WindowInteropHelper(this).Handle;

// Change the window style to remove icon and buttons
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));

base.OnSourceInitialized(e);
}

#region p/invoke

[DllImport("user32.dll")]
private static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

private const int GWL_STYLE = -16;

private const uint WS_SYSMENU = 0x80000;

#endregion

private void OnOkClick(object sender, RoutedEventArgs e)
{
DialogResult = true;
}

private void WebProxySetup(object sender, RoutedEventArgs e)
{
try
{
var type = Assembly.GetAssembly(typeof(IConnectionInfo)).GetType("LINQPad.UI.ProxyForm");

var ci = type.GetConstructor(new Type[] { });

using (var form = (Form)ci.Invoke(null))
{
form.ShowDialog();
}
}
catch (Exception ex)
{
MessageBox.Show("Couldn't show LINQPad Web proxy settings.\r\n" +
"Open it manually from Edit->Preferences->Web proxy.\r\n" +
$"{ex.Message}",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using LINQPad.Extensibility.DataContext;
using MessageBox = System.Windows.MessageBox;

namespace OData4.UI
{
public partial class ConnectionDialog
{
public ConnectionDialog(IConnectionInfo cxInfo)
{
InitializeComponent();
DataContext = new ConnectionProperties(cxInfo);
}

/// <summary>
/// Raises the <see cref="E:System.Windows.Window.SourceInitialized"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnSourceInitialized(EventArgs e)
{
IntPtr hwnd = new WindowInteropHelper(this).Handle;

// Change the window style to remove icon and buttons
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));

base.OnSourceInitialized(e);
}

#region p/invoke

[DllImport("user32.dll")]
private static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

private const int GWL_STYLE = -16;

private const uint WS_SYSMENU = 0x80000;

#endregion

private void OnOkClick(object sender, RoutedEventArgs e)
{
DialogResult = true;
}

private void WebProxySetup(object sender, RoutedEventArgs e)
{
try
{
var type = Assembly.GetAssembly(typeof(IConnectionInfo)).GetType("LINQPad.UI.ProxyForm");

var ci = type.GetConstructor(new Type[] { });

using (var form = (Form)ci.Invoke(null))
{
form.ShowDialog();
}
}
catch (Exception ex)
{
MessageBox.Show("Couldn't show LINQPad Web proxy settings.\r\n" +
"Open it manually from Edit->Preferences->Web proxy.\r\n" +
$"{ex.Message}",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
51 changes: 51 additions & 0 deletions UI/PasswordBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace OData4.UI
{
public class PasswordBehavior : Behavior<PasswordBox>
{
public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(PasswordBehavior), new PropertyMetadata(default(string)));

private bool _skipUpdate;

public string Password
{
get { return (string)GetValue(PasswordProperty); }
set { SetValue(PasswordProperty, value); }
}

protected override void OnAttached()
{
AssociatedObject.PasswordChanged += PasswordBox_PasswordChanged;
}

protected override void OnDetaching()
{
AssociatedObject.PasswordChanged -= PasswordBox_PasswordChanged;
}

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);

if (e.Property == PasswordProperty)
{
if (!_skipUpdate)
{
_skipUpdate = true;
AssociatedObject.Password = e.NewValue as string;
_skipUpdate = false;
}
}
}

private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
_skipUpdate = true;
Password = AssociatedObject.Password;
_skipUpdate = false;
}
}
}

0 comments on commit 15bee63

Please sign in to comment.