Can you change the position where the next character is input programmatically?

4 posts, 0 answers
  1. Tony
    Tony avatar
    111 posts
    Member since:
    May 2011

    Posted 12 Apr 2013 Link to this post

    I've got a RadMaskedDateTimeInput control that I use in a UserControl in my application.  My UserControl consists of the RadMaskedDateTimeInput control and two RepeatButtons:
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <telerik:RadMaskedDateTimeInput Focusable="True"
                                        Grid.Column="0"
                                        FormatString="{Binding Path=Mask, Mode=OneWay}"
                                        HorizontalAlignment="Stretch"
                                        HorizontalContentAlignment="Right"
                                        InputBehavior="Insert"
                                        IsClearButtonVisible="False"
                                        Margin="5"
                                        Mask="{Binding Path=Mask, Mode=OneWay}"
                                        Name="ValueBox"
                                        SelectionOnFocus="CaretToEnd"
                                        SpinMode="PositionAndValue"
                                        TextMode="MaskedText"
                                        UpdateValueEvent="PropertyChanged"
                                        Value="{Binding Converter={StaticResource TimeSpanConverter}, Path=Value, Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}"
                                        VerticalAlignment="Center" />
        <RepeatButton Click="IncrementButton_Click"
                      Focusable="False"
                      Grid.Column="1"
                      IsTabStop="False"
                      Name="IncrementButton">
            <Image>
                <Image.Style>
                    <Style TargetType="{x:Type Image}">
                        <Setter Property="Source"
                                Value="/CustomControls;component/Resources/VolumeUpDay.png" />
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=IncrementButton, Path=IsEnabled}" Value="false" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="DayTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpDisabledDay.png" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=IncrementButton, Path=IsEnabled}" Value="true" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpNight.png" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=IncrementButton, Path=IsEnabled}" Value="false" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpDisabledNight.png" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        </RepeatButton>
        <RepeatButton Click="DecrementButton_Click"
                      Focusable="False"
                      Grid.Column="2"
                      IsTabStop="False"
                      Name="DecrementButton">
            <Image>
                <Image.Style>
                    <Style TargetType="{x:Type Image}">
                        <Setter Property="Source"
                                Value="/CustomControls;component/Resources/VolumeDnDay.png" />
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=DecrementButton, Path=IsEnabled}" Value="false" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="DayTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnDisabledDay.png" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=DecrementButton, Path=IsEnabled}" Value="true" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnNight.png" />
                            </MultiDataTrigger>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding ElementName=DecrementButton, Path=IsEnabled}" Value="false" />
                                    <Condition Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime" />
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnDisabledNight.png" />
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        </RepeatButton>
    </Grid>

    Here is the code that gets executed when the user clicks on either of the two RepeatButtons:
    private void DecrementButton_Click( object sender, RoutedEventArgs e ) {
        ValueBox.CallSpin( false );
    }
     
    private void IncrementButton_Click( object sender, RoutedEventArgs e ) {
        ValueBox.CallSpin( true );
    }

    The Mask that I'm using for the control in this application is "HH:mm:ss.fff".  The control is used in an application that runs on a laptop with a touch screen.  It's intended for use in a police car while the officer is driving, so the controls are all big to make it easy for officers with sausage fingers to use.  One button has an arrow pointing up and the other has an arrow pointing down.  The idea is that touching either button causes the spin functionality of the RadMaskedTimeDateInput control to fire.

    My problem is that if the user clicks on either button without touching on anything in the RadMaskedDateTimeInput control first, the control wants to spin the "HH" part of the DateTime value.  I'd prefer it if the control would spin the ".fff" part in this situation instead.  But there doesn't seem to be a way to programmatically specify where the input position is in the control.

    How can I make this work?
  2. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 17 Apr 2013 Link to this post

    Hi Tony,

    In order to achieve your requirements you can reassign the Value property of the RadMaskedDateTimeInput in the Click event handlers of your RepeatButtons. You will have to create new DateTime variable, use the initial value of the control and create the new one. You can implement this approach like this:

    private void IncrementButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime? date = this.ValueBox.Value;
        DateTime newDate = new DateTime(date.Value.Year, date.Value.Month, date.Value.Day, date.Value.Hour, date.Value.Minute, date.Value.Second, date.Value.Millisecond + 1);
        this.ValueBox.Value = newDate;
    }
     
    private void DecrementButton_Click(object sender, RoutedEventArgs e)
    {
        DateTime? date = this.ValueBox.Value;
        DateTime newDate = new DateTime(date.Value.Year, date.Value.Month, date.Value.Day, date.Value.Hour, date.Value.Minute, date.Value.Second, date.Value.Millisecond - 1);
        this.ValueBox.Value = newDate;
    }
    I hope this will work for you.

    Regards,
    Pavel R. Pavlov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. UI for WPF is Visual Studio 2017 Ready
  4. Tony
    Tony avatar
    111 posts
    Member since:
    May 2011

    Posted 23 Apr 2013 Link to this post

    Pavel:

    That is not what I wanted the buttons to do.  I don't want the buttons to change the time by a millisecond.  I want them to act as though the user had pressed the up or down arrow keys on the keyboard.  And how much the control increases or decreases the value when an arrow key is pressed depends on where the cursor is in the input. 

    Is it possible to control the cursor's position in the control programmatically?  If so, how?

    Tony
  5. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 26 Apr 2013 Link to this post

    Hi Tony,

    When you press a key from the keyboard the focus stays where it is and this is why the control is able to change the corresponding (focused) number. Please note that when you click on a button (your increase/decrease buttons) you also change the target of the focus. Hence you will not be able to detect which number you want to change.

    However, you can overcome this issue by further customizing our RadMaskedDateTimeInput control and make it separate focus scope. Unfortunately, this is not supported out-of-the-box and you will have to implement. You can use this article as a start.

    Regards,
    Pavel R. Pavlov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top