Search code examples
c#wpftouch.net-4.5touch-event

IsManipulationEnabled = true prevents touch toggling a togglebutton


I am looking for a solution to making touch able to handle toggling a toggle button when IsManipulationEnabled = true. I have to keep on IsManipulationEnabled due to underlying 3d map.

Here is the test project I have been using.

<Window x:Class="TestingEventManager.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" IsManipulationEnabled="True">
<StackPanel HorizontalAlignment="Stretch">
<ToggleButton Height="40">
  <ToggleButton.Style>        
    <Style TargetType="ToggleButton">
      <Setter Property="Content" Value="OFF"/>
      <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
          <Setter Property="Content" Value="ON"/>
        </Trigger>           
      </Style.Triggers>
    </Style>
  </ToggleButton.Style>
</ToggleButton>
<ComboBox SelectedIndex="0" Height="40">      
  <ComboBoxItem>Test 1</ComboBoxItem>
  <ComboBoxItem>Test 2</ComboBoxItem>
</ComboBox>
</StackPanel>

I have looked into setting it in the app.xaml style, but setting it just for togglebutton seems to not extend down into the combobox style and it can be easily overridden by another style.

I also would not like to make a custom class because then everyone would need to remember to use this derived class.

Here is a msdn blog article that describes some of these issues with mixing touch MSDN blog article

And here is an article with someone having a similar problem, but she just extended the button. MSDN Social Article


Solution

  • Well last night I came up with somewhat of a solution that I am going to roll with in our code. It is not the best solution due to it always turning on ManipulationEnabled for every togglebutton and its manually handling the IsChecked now, but its the only thing I could come up with to always manipulate every togglebutton.

    private void EnableTouchDownTogglingOfToggleButton()
    {
      EventManager.RegisterClassHandler( typeof( ToggleButton ), ToggleButton.LoadedEvent, new RoutedEventHandler( TurnOnManipulaitonEnabled ) );
      EventManager.RegisterClassHandler( typeof( ToggleButton ), ToggleButton.TouchDownEvent, new RoutedEventHandler( EnableTouchDownTogglingHandler ) );
    }
    
    private void TurnOnManipulaitonEnabled( object sender, RoutedEventArgs e )
    {
      // need to make sure all toggle buttons behave the same so we always assume IsManipulationEnabled is true
      // otherwise it can open then close right after due to it firing again from mousedown being able to go through
      ToggleButton toggle = sender as ToggleButton;
      if ( toggle != null )
        toggle.IsManipulationEnabled = true;
    }
    
    private void EnableTouchDownTogglingHandler( object sender, RoutedEventArgs e )
    {
      ToggleButton toggle = sender as ToggleButton;
      if ( toggle != null )
        toggle.IsChecked ^= true;
    }