Есть ли способ шаблонирования RadioButton, поэтому он должен в стиле TabItem - PullRequest
0 голосов
/ 02 января 2011

Я пробовал:

<UniformGrid DockPanel.Dock="Top" Columns="2" Rows="1">
  <UniformGrid.Resources>   
    <Style TargetType="RadioButton">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="RadioButton">
            <TabItem IsSelected="{TemplateBinding IsChecked}">
              <TabItem.Header>
                <ContentPresenter Margin="5" />
              </TabItem.Header>                  
            </TabItem>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </UniformGrid.Resources>
  <RadioButton Content="By company name" />
  <RadioButton Content="By contact name" Grid.Column="1"/>
</UniformGrid>

На самом деле это работает, за исключением того, что не выбирает / не выбирает соответствующую вкладку.
Я бы предпочел RadioButtons, конечно, но мой клиент настаивает, что это должны быть вкладки.

Ответы [ 2 ]

1 голос
/ 02 января 2011

Я думаю, что проблема в том, что TabItem «съедает» щелчок мышью, поэтому RadioButton никогда не проверяется и не проверяется.Вы можете обернуть TabItem в рамку и установить IsHitTestVisible="False".При этом вы потеряете триггер IsMouseOver и т. Д., Поэтому вам придется заново добавить их из шаблона по умолчанию

Попробуйте что-то вроде этого

<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
    <GradientStop Color="#EAF6FD" Offset="0.15"/>
    <GradientStop Color="#D9F0FC" Offset=".5"/>
    <GradientStop Color="#BEE6FD" Offset=".5"/>
    <GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>

<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RadioButton">
                <Border BorderBrush="Transparent" BorderThickness="0" Background="Transparent" CornerRadius="0">
                    <TabItem x:Name="tabItem" IsSelected="{TemplateBinding IsChecked}" IsHitTestVisible="False">
                        <TabItem.Header>
                            <ContentPresenter Margin="5"/>
                        </TabItem.Header>
                    </TabItem>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" TargetName="tabItem" Value="{StaticResource TabItemHotBackground}"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Panel.ZIndex" Value="1"/>
                        <Setter Property="Background" TargetName="tabItem" Value="{StaticResource TabItemSelectedBackground}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="false"/>
                            <Condition Property="IsMouseOver" Value="true"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="tabItem" Value="{StaticResource TabItemHotBorderBrush}"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Обновление

<ControlTemplate TargetType="RadioButton">
    <Border BorderBrush="Transparent" BorderThickness="0" Background="Transparent" CornerRadius="0">
        <TabItem x:Name="tabItem" IsSelected="{TemplateBinding IsChecked}" IsHitTestVisible="False">
            <TabItem.Header>
                <ContentPresenter Margin="5"/>
            </TabItem.Header>
        </TabItem>
    </Border>
</ControlTemplate>

Обновление 2
Вы можете использовать Attached Behavior для вызова события MouseDown на RadioButton при нажатии TabItem.В качестве альтернативы вы можете просто установить IsChecked = "True" вместо вызова события щелчка

<ControlTemplate TargetType="RadioButton">
    <TabItem x:Name="tabItem" IsSelected="{TemplateBinding IsChecked}"
             local:LinkWithRadioButtonBehavior.LinkWithRadioButton="True">
        <TabItem.Header>
            <ContentPresenter Margin="5"/>
        </TabItem.Header>
    </TabItem>
</ControlTemplate>

LinkWithRadioButtonBehavior

public static class LinkWithRadioButtonBehavior 
{
    public static readonly DependencyProperty LinkWithRadioButtonProperty = 
        DependencyProperty.RegisterAttached 
        (
            "LinkWithRadioButton", 
            typeof(bool),
            typeof(LinkWithRadioButtonBehavior),
            new UIPropertyMetadata(false, OnLinkWithRadioButtonPropertyChanged) 
        );
    public static bool GetLinkWithRadioButton(DependencyObject obj) 
    {
        return (bool)obj.GetValue(LinkWithRadioButtonProperty); 
    }
    public static void SetLinkWithRadioButton(DependencyObject obj, bool value) 
    {
        obj.SetValue(LinkWithRadioButtonProperty, value); 
    }
    private static void OnLinkWithRadioButtonPropertyChanged(DependencyObject dpo, 
                                                             DependencyPropertyChangedEventArgs e) 
    {
        Control control = dpo as Control;
        if (control != null) 
        { 
            if ((bool)e.NewValue == true) 
            {
                control.PreviewMouseDown += OnMouseDown; 
            } 
            else 
            {
                control.PreviewMouseDown -= OnMouseDown; 
            } 
        } 
    }
    static void OnMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        Control control = sender as Control;
        MouseButtonEventArgs routedEventArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left);
        routedEventArgs.RoutedEvent = RadioButton.MouseDownEvent;
        routedEventArgs.Source = control;
        RadioButton clickedRadioButton = GetVisualParent<RadioButton>(control);
        clickedRadioButton.RaiseEvent(routedEventArgs);
    }
    public static T GetVisualParent<T>(object childObject) where T : Visual
    {
        DependencyObject child = childObject as DependencyObject;
        while ((child != null) && !(child is T))
        {
            child = VisualTreeHelper.GetParent(child);
        }
        return child as T;
    }
}
0 голосов
/ 03 июля 2013

Вы можете просто оформить радиокнопки как ToggleButtons и создать взаимоисключающие состояния, назначенные триггерам Blend Interaction события «Click».Это боль, но гораздо меньше, чем ответ, который вы приняли.Надеюсь, это кому-нибудь поможет

...