Синтаксис для привязки свойства ToggleButton IsChecked к присоединенному поведению RichTextBox

WPF.

У меня есть поведение:

public class RichTextBehavior : Behavior<RichTextBox>
    {
         public bool TextBold
        {
            get { return (bool)GetValue(TextBoldProperty); }
            set { SetValue(TextBoldProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TextBold.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextBoldProperty =
            DependencyProperty.Register("TextBold", typeof(bool), typeof(RichTextBehavior),
             new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextBoldChanged));

        private static void OnTextBoldChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = d as RichTextBehavior;
            TextRange tr = new TextRange(behavior.AssociatedObject.Selection.Start, behavior.AssociatedObject.Selection.End);
            if (tr == null)
                return;

            // This Works, but also adds keyboard commands.
            //EditingCommands.ToggleBold.Execute(null, behavior.AssociatedObject);

            if ((bool)e.NewValue)
                //TextSelection ts = richTextBox.Selection;

                tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
            else
                tr.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Normal);

        }

Это прикреплено к RichTextBox как:

 <RichTextBox x:Name="RichTextControl" ...
                            >
                        <i:Interaction.Behaviors>
                            <b:RichTextBehavior TextFont="{Binding ElementName=Fonttype, Path=SelectedItem, Mode=TwoWay}"/>
                        </i:Interaction.Behaviors>

                    </RichTextBox>

Я хотел бы привязать свойство ToggleButton IsChecked к свойству TextBold поведения (в XAML), что-то например:

<ToggleButton Name="ToggleBold"  Command="EditingCommands.ToggleBold" 
       CommandTarget="{Binding ElementName=RichTextControl}"
        IsChecked="{Binding ElementName=RichTextControl, Path=(TextBold), Mode=TwoWay}"
        .......................................           
 </ToggleButton>

Как это делается? Каков синтаксис? Любая идея высоко ценится. ТИА

Редактировать:

Я считаю, что это должно работать, но это не так. В действии нажатие кнопки Bold Toggle ИЗМЕНЯЕТ печатный текст в RichTextBox (как и должно быть с EditingCommands.ToggleBold), но, как и раньше, выделение текста уже в RichTextBox НЕ изменяет состояние ToggleBold при привязке к IsChecked имущество.

Я считаю, что это должно было сработать (но, похоже, не соблюдает привязку IsChecked):

 <ToggleButton Name="ToggleBold"  
Command="EditingCommands.ToggleBold" CommandTarget="{Binding ElementName=RichTextControl}"
    IsChecked="{Binding ElementName=RichTextControl, 
 Path=(b:RichTextBehavior.TextBold), Mode=TwoWay}"........

Я мог бы добавить, что по какой-то причине каждое нажатие клавиши в RichTextBox, кажется, дважды вызывает SelectionChanged в поведении (а не один раз, как я ожидал), и второй вызов, похоже, не имеет уже установленного значения первого вызова . Странный.


person Alan Wayne    schedule 01.03.2017    source источник


Ответы (2)


Вы можете обработать событие SelectionChanged в поведении:

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += RichTextBoxSelectionChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.SelectionChanged -= RichTextBoxSelectionChanged;
    }

и правильно установите TextBold, используя GetPropertyValue:

    void RichTextBoxSelectionChanged(object sender, System.Windows.RoutedEventArgs e)
    {
        TextRange tr = new TextRange(AssociatedObject.Selection.Start, AssociatedObject.Selection.End);
        if (tr == null)
            return;
        FontWeight g = (FontWeight)tr.GetPropertyValue(TextElement.FontWeightProperty); 
        TextBold = g == FontWeights.Bold;
    }  

Используйте двустороннюю привязку (я использую CheckBox):

<StackPanel> 
    <RichTextBox x:Name="RichTextControl" >
        <i:Interaction.Behaviors>
            <local:RichTextBehavior TextBold="{Binding ElementName=fonttype, Path=IsChecked, Mode=TwoWay}"/>
        </i:Interaction.Behaviors> 
    </RichTextBox>
    <CheckBox x:Name="fonttype"  Content="Is Bold"   /> 
</StackPanel> 
person Ron    schedule 01.03.2017
comment
Я не рассматривал возможность использования флажка. Есть ли проблема с ToggleButton? Пожалуйста, смотрите мое редактирование. Спасибо. - person Alan Wayne; 01.03.2017
comment
Работает и с ToggleButton. У вас были проблемы с его использованием? - person Ron; 01.03.2017
comment
Мне нужно многому научиться. По-видимому, использование IsChecked из ToggleButton/CheckBox снова вызывало SelectionChanged и/или способ, которым я указал привязку из ToggleButton, возможно, ссылался на другой объект, а не на поведение RichTextBox (я не знаю?). В любом случае удаление привязки IsChecked из ToggleButton (как вы сделали) и использование вашего решения работает отлично. Спасибо. :) - person Alan Wayne; 01.03.2017

Возможно, это то, что вы хотите:

     <RichTextBox x:Name="RichTextControl">
        <i:Interaction.Behaviors>
            <b:RichTextBehavior TextBold="{Binding ElementName=toggleBold,Path=IsChecked}" />
        </i:Interaction.Behaviors>
    </RichTextBox>
    <ToggleButton x:Name="toggleBold" Content="Bold" />
person WPInfo    schedule 01.03.2017
comment
На самом деле ищете его по-другому. т. е. целью является ToggleButton. Спасибо. - person Alan Wayne; 01.03.2017
comment
Извините, я не понимаю, что вы имеете в виду, это то, что вы хотите: добавить Mode=OneWayToSource в привязку? - person WPInfo; 01.03.2017
comment
Пробовал. Не повезло. - person Alan Wayne; 01.03.2017
comment
Теперь я понимаю, что на самом деле это тоже был правильный ответ, я просто слишком устал, чтобы распознать его. - person Alan Wayne; 02.03.2017