views:

684

answers:

1

For whatever reason, the KeyBindings for my UserControl aren't working as soon as my WPF Application loads. They do work after I press a button on the form but not when I set focus to the form by clicking or alt tabbing or moving or anything like that. And when they do work my enter keys print a random number. (sometimes 5, sometimes 7 etc...).

<UserControl x:Class="WpfCalculator.View.CalculatorView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300"
    >
<UserControl.InputBindings>
    <KeyBinding Key="DELETE" Command="{Binding Path=IBackspaceOnInput}" />
    <KeyBinding Key="BACKSPACE" Command="{Binding Path=IBackspaceOnInput}" />

    <KeyBinding Key="NUMPAD0" Command="{Binding Path=IAppendToUserInput}" CommandParameter="0" />
    <KeyBinding Key="NUMPAD1" Command="{Binding Path=IAppendToUserInput}" CommandParameter="1" />
    <KeyBinding Key="NUMPAD2" Command="{Binding Path=IAppendToUserInput}" CommandParameter="2" />
    <KeyBinding Key="NUMPAD3" Command="{Binding Path=IAppendToUserInput}" CommandParameter="3" />
    <KeyBinding Key="NUMPAD4" Command="{Binding Path=IAppendToUserInput}" CommandParameter="4" />
    <KeyBinding Key="NUMPAD5" Command="{Binding Path=IAppendToUserInput}" CommandParameter="5" />
    <KeyBinding Key="NUMPAD6" Command="{Binding Path=IAppendToUserInput}" CommandParameter="6" />
    <KeyBinding Key="NUMPAD7" Command="{Binding Path=IAppendToUserInput}" CommandParameter="7" />
    <KeyBinding Key="NUMPAD8" Command="{Binding Path=IAppendToUserInput}" CommandParameter="8" />
    <KeyBinding Key="NUMPAD9" Command="{Binding Path=IAppendToUserInput}" CommandParameter="9" />

    <KeyBinding Key="D0" Command="{Binding Path=IAppendToUserInput}" CommandParameter="0" />
    <KeyBinding Key="D1" Command="{Binding Path=IAppendToUserInput}" CommandParameter="1" />
    <KeyBinding Key="D2" Command="{Binding Path=IAppendToUserInput}" CommandParameter="2" />
    <KeyBinding Key="D3" Command="{Binding Path=IAppendToUserInput}" CommandParameter="3" />
    <KeyBinding Key="D4" Command="{Binding Path=IAppendToUserInput}" CommandParameter="4" />
    <KeyBinding Key="D5" Command="{Binding Path=IAppendToUserInput}" CommandParameter="5" />
    <KeyBinding Key="D6" Command="{Binding Path=IAppendToUserInput}" CommandParameter="6" />
    <KeyBinding Key="D7" Command="{Binding Path=IAppendToUserInput}" CommandParameter="7" />
    <KeyBinding Key="D8" Command="{Binding Path=IAppendToUserInput}" CommandParameter="8" />
    <KeyBinding Key="D9" Command="{Binding Path=IAppendToUserInput}" CommandParameter="9" />

    <KeyBinding Key="ADD" Command="{Binding Path=IAppendToUserInput}" CommandParameter="+" />
    <KeyBinding Key="SUBTRACT" Command="{Binding Path=IAppendToUserInput}" CommandParameter="-" />
    <KeyBinding Key="MULTIPLY" Command="{Binding Path=IAppendToUserInput}" CommandParameter="*" />
    <KeyBinding Key="DIVIDE" Command="{Binding Path=IAppendToUserInput}" CommandParameter="/" />

    <KeyBinding Key="Return" Command="{Binding Path=ICalculateExpression}" CommandParameter="" />
    <KeyBinding Key="Enter" Command="{Binding Path=ICalculateExpression}" CommandParameter="" />
    <KeyBinding Key="Escape" Command="{Binding Path=IClearInput}" CommandParameter="" />

    <KeyBinding Gesture="CTRL+M" Command="{Binding Path=IRememberExpression}" CommandParameter="" />
    <KeyBinding Gesture="CTRL+R" Command="{Binding Path=IRecallExpression}" CommandParameter="" />
    <KeyBinding Gesture="CTRL+X" Command="{Binding Path=IForgetExpression}" CommandParameter="" />

    <KeyBinding Key="Left" Command="{Binding Path=IMMoveCursor}" CommandParameter="1" />
    <KeyBinding Key="Right" Command="{Binding Path=IMMoveCursor}" CommandParameter="-1" />

</UserControl.InputBindings>

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="305" Width="489">
    <TextBox Name="input" HorizontalAlignment="Right"  IsReadOnly="True" Margin="0,12,200,271" Text="{Binding Path=UserInput}" Width="275" />
    <Button Content="CE" Margin="143,0,323,147" Command="{Binding Path=IBackspaceOnInput}" CommandParameter="" Height="23" VerticalAlignment="Bottom" />
    <Button Content="1" Height="23" HorizontalAlignment="Right" Margin="0,106,294,176" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="1" />
    <Button Content="2" Height="23" HorizontalAlignment="Right" Margin="0,106,265,176" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="2" />
    <Button Content="3" Height="23" HorizontalAlignment="Right" Margin="0,106,236,176" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="3" />
    <Button Content="4" Height="23" HorizontalAlignment="Right" Margin="0,77,294,205" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="4" />
    <Button Content="5" Height="23" HorizontalAlignment="Right" Margin="0,77,236,205" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="5" />
    <Button Content="6" Height="23" HorizontalAlignment="Right" Margin="0,77,265,205" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="6" />
    <Button Content="7" Height="23" HorizontalAlignment="Right" Margin="0,48,294,234" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="7" />
    <Button Content="8" Height="23" HorizontalAlignment="Right" Margin="0,48,265,234" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="8" />
    <Button Content="9" Height="23" HorizontalAlignment="Right" Margin="0,48,236,234" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="9" />
    <Button Content="0" Height="23" HorizontalAlignment="Left" Margin="201,135,0,147" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="0" />

    <Button Content="+" Height="23" HorizontalAlignment="Right" Margin="0,48,201,234" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="+" />
    <Button Content="-" Height="23" HorizontalAlignment="Right" Margin="0,77,201,205" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="-" />
    <Button Content="*" Height="23" HorizontalAlignment="Right" Margin="0,106,201,176" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="*" />
    <Button Content="/" Height="23" HorizontalAlignment="Right" Margin="0,135,201,147" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="/" />
    <Button Content="." Height="23" HorizontalAlignment="Right" Margin="0,135,236,147" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="9" />

    <Button Content="C" HorizontalAlignment="Right" Margin="0,164,323,118" Width="23" Command="{Binding Path=IClearInput}" CommandParameter="" />
    <Button Content="MC" Height="23" HorizontalAlignment="Right" Margin="0,0,323,234" VerticalAlignment="Bottom" Width="23" Command="{Binding Path=IForgetExpression}" CommandParameter=""/>
    <Button Content="M+" Height="23" HorizontalAlignment="Right" Margin="0,0,323,176" VerticalAlignment="Bottom" Width="23" Command="{Binding Path=IRememberExpression}" CommandParameter=""/>
    <Button Content="MR" Height="23" HorizontalAlignment="Right" Margin="0,0,323,205" VerticalAlignment="Bottom" Width="23" Command="{Binding Path=IRecallExpression}" CommandParameter=""/>

    <Expander ExpandDirection="Left" Header="History" Height="91" HorizontalAlignment="Right" Margin="0,193,200,0" VerticalAlignment="Top" Width="275">
        <ListView ItemsSource="{Binding Path=History}" >
            <ListView.View>
                <GridView >
                    <GridViewColumn Header="Start" DisplayMemberBinding="{Binding Started}"/>
                    <GridViewColumn Header="End" DisplayMemberBinding="{Binding Completed}"/>
                    <GridViewColumn Header="Expression" DisplayMemberBinding="{Binding Calculation}"/>
                    <GridViewColumn Header="Solution" DisplayMemberBinding="{Binding Result}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Expander>
    <Button Command="{Binding Path=ICalculateExpression}" CommandParameter="" IsEnabled="{Binding Path=IsEqualsBtnEnabled}" Content="=" Height="23" Margin="172,0,236,118" VerticalAlignment="Bottom" />

</Grid></UserControl>

I really haven't come across anyone else with this particular problem so I'm not really sure what to give any more than this. Let me know if there is any other info required?

+1  A: 

Have you verified that the control actually has focus when it loads by using Mole? It could be that whatever your parent control is keeps focus until your buttons are selected manually. As for the Enter keys, it sounds as if they are probably selecting the last clicked button since it would still have focus instead of firing your commands.

You may need to look at your commands as I'm not sure the declarations are set up correctly. For KeyBindings, your command should be referenced in XAML as a CommandReference, like this article describes.

Jeff Wain
I'm going to try using CommandReference to bind the inputs as you suggest. I currently have visual studio 2010 so I haven't tried mole. (Do you perhaps know of another way to check this?) But I am a bit confused about some information presented in the article. According to the article I should be getting an exception but as of right now but my application is running fine short of the issues I am currently dealing with at the moment.
Terrance
Your answer did help as far as button click behavior but, I just had to useFocusManager.FocusedElement="{Binding ElementName=input}" to set the focus of the textbox. But the Command Reference made no change to the app although I'm definitely going to keep it in mind for Attaching non-dependency properties when I'm in a bind in the future. No stupid binding pun intended. lol
Terrance
An example of the ClickMode: I mentioned eariler<Button Content="1" Height="23" HorizontalAlignment="Right" Margin="0,106,294,176" Width="23" Command="{Binding Path=IAppendToUserInput}" CommandParameter="1" ClickMode="Press" />
Terrance
Good to know the command reference didn't make a difference, but glad this helped regardless. I hadn't run across this particular scenario before, so I'll make sure to jot this down so I also have it in the future.
Jeff Wain