theperfectstorm
asked on
WPF Keyboard layout and event handling
My question stems from trying to achieve simplified and efficient code. I have already got a custom keyboard to function, but would like it to be better if possible. I have attached a simplified version of the keyboard and would like any suggestions on laying out the keys for better performance and code access. Right now I use several for loops to add event to the keys because they exist in different panels. Is there a "pretty way" to put them in one panel while still making the keys shifted like a real keyboard. By pretty, I mean, not too many margin or columnspan parameters. Maybe a canvas is the best solution?
I started with the following to web pages which I have to give credit to.
http://ascendedguard.com/2007/08/wpf-virtual-keyboard.html
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2092883&SiteID=1
<!-- XAML -->
<grid>
<Grid.RowDefinitions>
<RowDefinition/><RowDefini tion/> <RowDefinition/><RowDefini tion/><Row Definition />
</Grid.RowDefinitions>
<DockPanel Name="R1" HorizontalAlignment="Cente r" Grid.Row="0">
<Button Name="Key1" Content="1" Style="{StaticResource AlphaNum}" />
<Button Name="Key2" Content="2" Style="{StaticResource AlphaNum}" />
<Button Name="Delete" Content="Delete" Style="{StaticResource AlphaNum}" Width="55" />
</DockPanel>
<DockPanel Name="R2" HorizontalAlignment="Cente r" Grid.Row="1">
<Button Name="KeyQ" Content="Q" Style="{StaticResource AlphaNum}" />
</DockPanel>
<DockPanel Name="R3" HorizontalAlignment="Cente r" Grid.Row="2">
<Button Name="KeyA" Content="A" Style="{StaticResource AlphaNum}" />
<Button Name="Enter" Content="Enter" Style="{StaticResource AlphaNum}" Width="75" />
</DockPanel>
<DockPanel Name="R4" HorizontalAlignment="Cente r" Grid.Row="3">
<Button Name="Shift1" Content="Shift" Style="{StaticResource AlphaNum}" Width="75" />
<Button Name="KeyZ" Content="Z" Style="{StaticResource AlphaNum}" />
</DockPanel>
<DockPanel Name="R5" HorizontalAlignment="Cente r" Grid.Row="4">
<Button Name="Space" Content="Space" Style="{StaticResource AlphaNum}" Width="300" />
</DockPanel>
</Grid>
// Code Behind
foreach (Button b in R1.Children)
{
b.Focusable = false;
if (b.Content.ToString().Leng th <= 1)
b.Click += new RoutedEventHandler(OnKeyCl ick);
else
b.Click += new RoutedEventHandler(OnSpeci alKeyClick );
}
foreach (Button b in R2.Children)
foreach (Button b in R3.Children)
foreach (Button b in R4.Children)
foreach (Button b in R5.Children)
Thanks,
Jeff
I started with the following to web pages which I have to give credit to.
http://ascendedguard.com/2007/08/wpf-virtual-keyboard.html
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2092883&SiteID=1
<!-- XAML -->
<grid>
<Grid.RowDefinitions>
<RowDefinition/><RowDefini
</Grid.RowDefinitions>
<DockPanel Name="R1" HorizontalAlignment="Cente
<Button Name="Key1" Content="1" Style="{StaticResource AlphaNum}" />
<Button Name="Key2" Content="2" Style="{StaticResource AlphaNum}" />
<Button Name="Delete" Content="Delete" Style="{StaticResource AlphaNum}" Width="55" />
</DockPanel>
<DockPanel Name="R2" HorizontalAlignment="Cente
<Button Name="KeyQ" Content="Q" Style="{StaticResource AlphaNum}" />
</DockPanel>
<DockPanel Name="R3" HorizontalAlignment="Cente
<Button Name="KeyA" Content="A" Style="{StaticResource AlphaNum}" />
<Button Name="Enter" Content="Enter" Style="{StaticResource AlphaNum}" Width="75" />
</DockPanel>
<DockPanel Name="R4" HorizontalAlignment="Cente
<Button Name="Shift1" Content="Shift" Style="{StaticResource AlphaNum}" Width="75" />
<Button Name="KeyZ" Content="Z" Style="{StaticResource AlphaNum}" />
</DockPanel>
<DockPanel Name="R5" HorizontalAlignment="Cente
<Button Name="Space" Content="Space" Style="{StaticResource AlphaNum}" Width="300" />
</DockPanel>
</Grid>
// Code Behind
foreach (Button b in R1.Children)
{
b.Focusable = false;
if (b.Content.ToString().Leng
b.Click += new RoutedEventHandler(OnKeyCl
else
b.Click += new RoutedEventHandler(OnSpeci
}
foreach (Button b in R2.Children)
foreach (Button b in R3.Children)
foreach (Button b in R4.Children)
foreach (Button b in R5.Children)
Thanks,
Jeff
Are you still looking for a solution?
Bob
Bob
ASKER
I don't think so. At this point, it looks like the canvas will create the most efficient and flexible layout, but does not simplify the access from code behind. I am going to stick with DockPanels for now, but may change to canvas if I run into performance problems.
I created an InputPanel user control, using Grid with five RowDefinition levels, and all the keys layed out nicely.
Bob
Bob
ASKER
Did you use columnspan, margin, or separate Grids to get the keys to be slightly offset of each other?
For me the grid forces the keys to be lined up in columns (The "Q" directly over the "A" and the "Z" directly under the "A"). But on a standard keyboard, the "Q", "A", and "Z" are slightly offset to right of each other. This was the affect I was trying for, but this required Grids within a Grid or separate DockPanels. Other ways worked as well, but each required independent rows.
Thanks for your comments.
For me the grid forces the keys to be lined up in columns (The "Q" directly over the "A" and the "Z" directly under the "A"). But on a standard keyboard, the "Q", "A", and "Z" are slightly offset to right of each other. This was the affect I was trying for, but this required Grids within a Grid or separate DockPanels. Other ways worked as well, but each required independent rows.
Thanks for your comments.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
This is great!
ASKER
DockPanel [] panels = new DockPanel[5] {R1,R2,R3,R4,R5};
foreach (DockPanel p in panels)
foreach (Button b in p.Children)
{
b.Focusable = false;
if (b.Content.ToString().Leng
b.Click += new RoutedEventHandler(OnKeyCl
else
b.Click += new RoutedEventHandler(OnSpeci
}