Wpf - Botón con un Check

Descripción general:

- FALTA(1) - FALTA EL texto para generar la etiqueta la etiqueta

Wpf - Botón con un Check

Se me ha presentado el ¿Problema? De indicar que una opción esta elegida usando un botón que se quede pulsado. Despues de dar muchas vueltas, he visto que en WPF no se puede hacer directamente (creo) asi que he estado pensando :-)

Lo primero que se me ha ocurrido es usar un CheckBox, y usar estilos para cambiar su aspecto, pero se ha complicado rápidamente, y no estaba por la labor de crear un nuevo control

Después se me ha ocurrido usar un menú con la opción [ IsCheckable="True" ] , y ha funcionado y cumple con lo que necesito y ademas de una forma sencilla

Imágenes del Botón
El Botón Botón Unchecked Botón Checked
Opción Check Desactivada
Opción Check Activada

El código XAML

<Window x:Class = "MainWindow"
        xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable = "d"
        Title = "MainWindow" Height = "150" Width = "200">
    <Window.Resources>
        <RoutedUICommand x:Key = "RCBotonCorrectorOrtografico"
        Text = "Activa, / desactiva el corrector ortográfico del TextBox (Usando el Botón)" />
        <RoutedUICommand x:Key = "RCBotonMenuItemCorrectorOrtografico"
        Text = "Activa, / desactiva el corrector ortográfico del TextBox (Usando el MenuItem del Botón)" />
    </Window.Resources>
    
    <Window.CommandBindings>
        <!-- Una observación -->
        <!-- Estos dos Command llaman a la misma función CanExecute -->
        <CommandBinding Command = "{StaticResource RCBotonCorrectorOrtografico}"
                        Executed = "BotonCorrectorOrtograficoCmd_Executed"
                        CanExecute = "BotonCorrectorOrtograficoCmd_CanExecute"/>
        <CommandBinding Command = "{StaticResource RCBotonMenuItemCorrectorOrtografico}"
                        Executed = "BotonMenuItemCorrectorOrtograficoCmd_Executed"
                        CanExecute = "BotonCorrectorOrtograficoCmd_CanExecute"/>
    </Window.CommandBindings>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height = "auto" />
            <RowDefinition Height = "auto" />
        </Grid.RowDefinitions>
        
        <!-- El Botón con un check (para incluirlo en una barra de botones) -->
        <!-- ¡Atención!  El Botón y el Menu, usan el mismo [Command] -->
        <Button Grid.Row = "0"
                                    x:Name = "ButtonCorrectorOrtografico"
                                    HorizontalAlignment = "Stretch" VerticalAlignment = "Top"
                                    Width = "40"
                                    Command = "{StaticResource RCBotonCorrectorOrtografico}"  >
            <Button.Content>
                <StackPanel  Orientation = "Horizontal">
                    <Menu HorizontalAlignment = "Left" VerticalAlignment = "Center">
                        <MenuItem x:Name = "MenuItemSpellChecker"
                                                      Header = ""
                                                      IsCheckable = "True" IsChecked = "False"
                                                      Width = "16" Height = "16"
                                                      HorizontalAlignment = "Left" VerticalAlignment = "Center"
                                                      Command = "{StaticResource RCBotonMenuItemCorrectorOrtografico}"/>
                    </Menu>
                    <!-- Imagen copiada de VS2019 Image Library.-->
                    <!-- Directorio [SpellingCheck] -->
                    <!-- Fichero    [SpellingCheck_16x.xaml] -->
                    <Viewbox Width = "16" Height = "16" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation">
                        <Rectangle Width = "16" Height = "16">
                            <Rectangle.Fill>
                                <DrawingBrush>
                                    <DrawingBrush.Drawing>
                                        <DrawingGroup>
                                            <DrawingGroup.Children>
                                                <GeometryDrawing Brush = "#00FFFFFF" Geometry = "F1M16,16L0,16 0,0 16,0z" />
                                                <GeometryDrawing Brush = "#FFF6F6F6" Geometry = "F1M16,6L12.382,6 12.148,6.467 12.148,6.121 12.141,5.847 12.148,5.853 12.148,2.404 11.555,2.14C11.447,2.092 11.311,2.044 11.125,1.993 10.93,1.943 10.719,1.919 10.481,1.919 10.081,1.919 9.711,1.996 9.384,2.146 9.032,2.307 8.733,2.545 8.496,2.853 8.487,2.864 8.481,2.879 8.472,2.892 8.3,2.637 8.095,2.418 7.847,2.26 7.525,2.052 7.149,1.946 6.73,1.946L6.697,1.946 6.697,0 4,0 4,2.365C3.87,2.276 3.73,2.199 3.578,2.138 3.29,2.023 2.96,1.965 2.598,1.965 2.424,1.965 2.247,1.98 2.047,2.015 1.882,2.046 1.723,2.082 1.586,2.124 1.434,2.169 1.294,2.219 1.15,2.28 0.987,2.353 0.865,2.422 0.775,2.484L0.345000000000001,2.783 0.345000000000001,4.591C0.244999999999999,4.748 0.167,4.919 0.109999999999999,5.102 0.0370000000000008,5.338 0,5.593 0,5.857 0,6.135 0.0429999999999993,6.4 0.129,6.648 0.223000000000001,6.918 0.368,7.159 0.558,7.363 0.752000000000001,7.571 0.991,7.733 1.266,7.843 1.523,7.947 1.811,8 2.12,8 2.351,8 2.569,7.969 2.774,7.906L4.962,7.906 4.962,7.887 5.977,7.887C6.164,7.949 6.368,7.98 6.583,7.98 7,7.98 7.381,7.877 7.707,7.678 7.985,7.51 8.218,7.277 8.41,7 8.433,7.031 8.448,7.068 8.472,7.099 8.699,7.392 8.981,7.621 9.309,7.779 9.634,7.937 9.998,8.017 10.391,8.017 10.532,8.017 10.666,8.007 10.801,7.986 10.922,7.966 11.031,7.942 11.117,7.917 11.233,7.885 11.337,7.847 11.436,7.803 11.459,7.792 11.475,7.783 11.496,7.772L10,10.764 9.618,10 5.382,10 8.382,16 11.618,16 16,7.236z" />
                                                <GeometryDrawing Brush = "#FF414141" Geometry = "F1M13,7L10,13 9,11 7,11 9,15 11,15 15,7z" />
                                                <GeometryDrawing Brush = "#FF414141" Geometry = "F1M3.1836,5.3809C3.1836,5.5119 3.1626,5.6329 3.1246,5.7459 3.0866,5.8579 3.0326,5.9569 2.9596,6.0409 2.8876,6.1249 2.8026,6.1919 2.7046,6.2399 2.6036,6.2889 2.4916,6.3129 2.3676,6.3129 2.2776,6.3129 2.1976,6.2989 2.1246,6.2719 2.0516,6.2439 1.9906,6.2069 1.9396,6.1579 1.8896,6.1109 1.8506,6.0529 1.8236,5.9859 1.7956,5.9179 1.7826,5.8459 1.7826,5.7679 1.7826,5.6819 1.7916,5.6039 1.8096,5.5349 1.8276,5.4669 1.8606,5.4079 1.9076,5.3559 1.9546,5.3029 2.0196,5.2579 2.1026,5.2229 2.1856,5.1899 2.2916,5.1619 2.4226,5.1449L3.1836,5.0349z M3.6296,3.3609C3.5186,3.2329 3.3766,3.1349 3.2056,3.0669 3.0356,2.9979 2.8316,2.9649 2.5976,2.9649 2.4786,2.9649 2.3566,2.9769 2.2296,2.9979 2.1036,3.0219 1.9816,3.0489 1.8676,3.0839 1.7536,3.1169 1.6506,3.1539 1.5576,3.1929 1.4656,3.2349 1.3956,3.2719 1.3446,3.3069L1.3446,4.0739C1.5026,3.9429 1.6856,3.8399 1.8886,3.7619 2.0926,3.6839 2.3016,3.6449 2.5156,3.6449 2.7286,3.6449 2.8926,3.7069 3.0096,3.8299 3.1256,3.9549 3.1836,4.1539 3.1836,4.4299L2.1536,4.5839C1.9496,4.6109 1.7746,4.6619 1.6276,4.7359 1.4826,4.8109 1.3636,4.9019 1.2706,5.0159 1.1766,5.1269 1.1096,5.2539 1.0656,5.3969 1.0216,5.5389 0.9996,5.6939 0.9996,5.8579 0.9996,6.0269 1.0256,6.1799 1.0746,6.3199 1.1226,6.4609 1.1956,6.5799 1.2896,6.6819 1.3826,6.7809 1.4996,6.8599 1.6416,6.9159 1.7816,6.9729 1.9396,6.9999 2.1206,6.9999 2.3496,6.9999 2.5506,6.9469 2.7236,6.8399 2.8966,6.7349 3.0426,6.5799 3.1626,6.3769L3.1766,6.3769 3.1766,6.9059 3.9616,6.9059 3.9616,4.4689C3.9616,4.2309 3.9346,4.0179 3.8786,3.8319 3.8246,3.6489 3.7406,3.4899 3.6296,3.3609" />
                                                <GeometryDrawing Brush = "#FF414141" Geometry = "F1M6.1768,3.7383C6.2768,3.6833 6.3868,3.6563 6.5078,3.6563 6.6298,3.6563 6.7398,3.6833 6.8348,3.7383 6.9308,3.7933 7.0118,3.8733 7.0788,3.9763 7.1458,4.0823 7.1958,4.2073 7.2298,4.3533 7.2638,4.5003 7.2808,4.6643 7.2808,4.8473 7.2808,5.0823 7.2618,5.2893 7.2218,5.4683 7.1828,5.6483 7.1268,5.7973 7.0538,5.9143 6.9818,6.0313 6.8938,6.1213 6.7898,6.1793 6.6858,6.2403 6.5708,6.2713 6.4408,6.2713 6.3328,6.2713 6.2318,6.2463 6.1398,6.1953 6.0488,6.1463 5.9698,6.0763 5.9028,5.9883 5.8358,5.9023 5.7848,5.7993 5.7478,5.6813 5.7108,5.5643 5.6918,5.4373 5.6918,5.3013L5.6918,4.7953C5.6918,4.6253 5.7118,4.4683 5.7518,4.3303 5.7918,4.1913 5.8478,4.0723 5.9198,3.9703 5.9918,3.8713 6.0758,3.7933 6.1768,3.7383 M5.7098,3.6563L5.6978,3.6563 5.6978,1.0003 4.9998,1.0003 4.9998,6.8863 5.6978,6.8863 5.6978,6.4023 5.7098,6.4023C5.7538,6.4843 5.8048,6.5603 5.8618,6.6313 5.9178,6.7013 5.9808,6.7633 6.0528,6.8163 6.1238,6.8693 6.2038,6.9083 6.2908,6.9373 6.3788,6.9673 6.4768,6.9803 6.5828,6.9803 6.8138,6.9803 7.0168,6.9273 7.1928,6.8203 7.3678,6.7153 7.5158,6.5663 7.6358,6.3773 7.7558,6.1893 7.8468,5.9653 7.9078,5.7053 7.9688,5.4453 7.9998,5.1663 7.9998,4.8613 7.9998,4.6033 7.9748,4.3593 7.9258,4.1273 7.8758,3.8943 7.8008,3.6913 7.6978,3.5153 7.5948,3.3403 7.4628,3.2013 7.3038,3.0993 7.1438,2.9963 6.9518,2.9463 6.7308,2.9463 6.6078,2.9463 6.4958,2.9643 6.3948,2.9983 6.2918,3.0333 6.1998,3.0823 6.1158,3.1443 6.0318,3.2073 5.9578,3.2813 5.8908,3.3673 5.8248,3.4553 5.7638,3.5503 5.7098,3.6563" />
                                                <GeometryDrawing Brush = "#FF414141" Geometry = "F1M11.0215,6.8926C10.9705,6.9146 10.9145,6.9356 10.8505,6.9536 10.7875,6.9716 10.7165,6.9866 10.6385,6.9986 10.5625,7.0106 10.4785,7.0166 10.3905,7.0166 10.1495,7.0166 9.9335,6.9706 9.7445,6.8786 9.5545,6.7876 9.3935,6.6556 9.2615,6.4856 9.1295,6.3146 9.0295,6.1086 8.9605,5.8676 8.8915,5.6256 8.8565,5.3566 8.8565,5.0576 8.8565,4.7066 8.8935,4.3996 8.9675,4.1326 9.0415,3.8676 9.1475,3.6446 9.2875,3.4646 9.4255,3.2846 9.5955,3.1486 9.7975,3.0566 10.0005,2.9636 10.2275,2.9186 10.4815,2.9186 10.6345,2.9186 10.7655,2.9336 10.8765,2.9616 10.9875,2.9926 11.0785,3.0226 11.1485,3.0536L11.1485,3.7946C11.0805,3.7416 10.9935,3.6926 10.8885,3.6496 10.7835,3.6066 10.6625,3.5836 10.5265,3.5836 10.3845,3.5836 10.2585,3.6186 10.1505,3.6846 10.0415,3.7526 9.9495,3.8476 9.8755,3.9696 9.8005,4.0916 9.7445,4.2406 9.7055,4.4136 9.6665,4.5866 9.6465,4.7786 9.6465,4.9886 9.6465,5.2046 9.6665,5.3956 9.7055,5.5646 9.7445,5.7336 9.7995,5.8746 9.8735,5.9916 9.9455,6.1076 10.0335,6.1966 10.1375,6.2566 10.2425,6.3176 10.3605,6.3486 10.4925,6.3486 10.6305,6.3486 10.7555,6.3246 10.8675,6.2776 10.9785,6.2306 11.0725,6.1786 11.1485,6.1216L11.1485,6.8286C11.1135,6.8486,11.0705,6.8706,11.0215,6.8926" />
                                            </DrawingGroup.Children>
                                        </DrawingGroup>
                                    </DrawingBrush.Drawing>
                                </DrawingBrush>
                            </Rectangle.Fill>
                        </Rectangle>
                    </Viewbox>
                </StackPanel>
            </Button.Content>
            <Button.ToolTip>
                <StackPanel Orientation = "Vertical">
                    <TextBlock Text = "Activa / desactiva el corrector ortográfico del TextBox" />
                </StackPanel>
            </Button.ToolTip>
        </Button>
        <!-- Para comprobar que funciona -->
        <TextBox Grid.Row = "1" x:Name = "ControlLocalTextBox"
                 HorizontalAlignment = "Stretch" VerticalAlignment = "Top"
                 Height = "23"  TextWrapping = "Wrap"
        Text = "camion" />
    </Grid>
</Window>

El código Visual Basic

#Region "ButtonCorrectorOrtografico"
        '--------------------------------------
        ' corrector Ortográfico
        Private Sub BotonCorrectorOrtograficoCmd_Executed(sender As Object, e As ExecutedRoutedEventArgs)
             ' Activar el corrector ortográfico de un TextBox
             ' hay que mantener el check del menu sincronizado con el botón
             Me.MenuItemSpellChecker.IsChecked = Not (Me.MenuItemSpellChecker.IsChecked)
             '------------------------------------------------
             ' después hacer la operación
             '------------------------------------------------
             ' Se escribe en función independiente porque es una operación
             ' que se llama desde varios (dos) sitios
             Call AccionBotonCorrectorOrtogáfico()
             '----
             ' Marcar el evento como ejecutado
             e.Handled = True
        End Sub

        ' Esta función se llama por dos Command
        ' [RCBotonCorrectorOrtografico]......... Se dispara al pulsar el botón
        ' [RCBotonMenuItemCorrectorOrtografico]  Se dispara al pulsar el menu del botón
        Private Sub BotonCorrectorOrtograficoCmd_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs)
             '-------------------------------------
             ' Siempre se puede realizar esta operación
             '-----------------------------
             e.CanExecute = True
             ' Marcar el evento como controlado.
             e.Handled = True
        End Sub

        ' los eventos de pulsar el menu del botón
        ' que son independientes de los de pulsar el botón
        ' son dos controles cons sus eventos juntos que deben funcionar sincronizados
        Private Sub BotonMenuItemCorrectorOrtograficoCmd_Executed(sender As Object, e As ExecutedRoutedEventArgs)
             '---
             ' Aquí no se cambia el check del menu porque ya lo he cambiado al pulsarlo
             '------------------------------------------------
             ' después hacer la operación
             '------------------------------------------------
             ' Se escribe en función independiente porque es una operación
             ' que se llama desde varios (dos) sitios
             Call AccionBotonCorrectorOrtogáfico()
             '----
             ' Marcar el evento como ejecutado
             e.Handled = True
        End Sub

        ' Borrable después de verificar que todo funciona
        Dim contador As Integer

        ''' <summary>
        ''' Función que hace el trabajo real de activar / desactivar el corrector ortográfico
        ''' </summary>
        Private Sub AccionBotonCorrectorOrtogáfico()
             '-------------------------------------------------------
             ' Borrable después de verificar que todo funciona
             ' Uso un contador para verificar que cada vez que pulse el botón
             ' se ejecuta esta función UNA UNICA vez
             ' [camion], le falta el acento. cuando el corrector este activado
             ' aparecerá subrayada como falta de ortografía
             contador + = 1
             Me.ControlLocalTextBox.Text = String.Format("- Pulsación  [{0}]  Camion ", contador)
             '--------------------------------------------------------------
             ' activar / desactivar el corrector ortográfico de un textBox
             ZSpellCheck = Not ZSpellCheck
        End Sub

        ''' <summary>
        ''' Activa / desactiva el corrector ortográfico del TextBox
        ''' </summary>
        ''' <value>
        '''   Valor lógico <see cref = "System.boolean">Boolean</see>
        '''   [True] el corrector ortográfico se activa, [False] en caso contrario
        ''' </value>
        ''' <remarks>
        ''' <code>
        '''   ' Enable spellchecking on the TextBox.
        '''    [TextBox].SpellCheck.IsEnabled = True
        ''' </code>
        ''' </remarks>
        Public Property ZSpellCheck As Boolean
              Get
                    If Me.ControlLocalTextBox Is Nothing Then Return False
                    Return Me.ControlLocalTextBox.SpellCheck.IsEnabled
              End Get
               Set(value As Boolean)
                    Me.ControlLocalTextBox.SpellCheck.IsEnabled = value
              End Set
        End Property

#End Region