(附加行为)的依赖属性没有被附加属性(另一个附加行为)更新

时间:2017-03-27 05:36:44

标签: c# wpf xaml

WPF。

在XAML中,我有一个Canvas,它将保存TextBlocks,其位置由RichTextBox控件收集的信息决定。 Canvas和RichTextBox都附加了行为,这些行为添加了"大纲"属性。

我的目标是让RichTextBox从其RichTextBoxSelectionChanged事件中设置outline属性。随着文本输入RichTextBox,outline属性将不断变化。

我需要" OutlineCanvas"获取Outline属性中的更改并通过将TextBlocks放在已分配的Canvas中来对其进行操作。

由于我无法获得的原因,以下代码设置了"大纲"在RichTextBox中,但它没有被OutlineCanvas拾取。

看起来好像OutlineCanvas的行为是在ONCE上启动的,但它并没有拾取在RichTextBox行为中设置的Outline。

我哪里错了?该怎么做?

TIA

XAML
<Canvas Grid.Column="0" Name="OutlineCanvas" Background="Azure" >
                    <i:Interaction.Behaviors>
                        <b:OutlineBehavior Outline="{Binding ElementName=RichTextControl, Path=(b:RichTextBehavior.Outline)}"/> 
                    </i:Interaction.Behaviors>
                </Canvas>

  <RichTextBox x:Name="RichTextControl" Grid.Column="1"
                               a:SmartAdorner.Visible="{Binding TranscriptionLayer.IsAdornerVisible}"
                                Panel.ZIndex="{Binding TranscriptionLayer.ZIndex}"  Cursor="IBeam"                               
                                Height="{Binding VirtualPage.Height}" 
                                Visibility="{Binding Path=TranscriptionLayer.Visibility}"  
                             SpellCheck.IsEnabled="True" 
                             VerticalScrollBarVisibility="Auto" 
                             AcceptsReturn="True" AcceptsTab="True"
                            >

 <i:Interaction.Behaviors>    
                        <b:RichTextBehavior 
                                SelectedText="{Binding  TranscriptionLayer.SelectedText}"                              
                                Image="{Binding TranscriptionLayer.Image}"
                                MoveImage="{Binding TranscriptionLayer.MoveImage}"
                                DeleteImage="{Binding TranscriptionLayer.DeleteImage}"
                            />
                    </i:Interaction.Behaviors>



C#
public class OutlineBehavior : Behavior<Canvas>
    {
        // The XAML attaches the behavior when it is instantiated.
        protected override void OnAttached()
        {
            base.OnAttached();
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
        }



        public static ProgressNoteOutline GetOutline(DependencyObject obj)
        {
            return (ProgressNoteOutline)obj.GetValue(OutlineProperty);
        }

        public static void SetOutline(DependencyObject obj, ProgressNoteOutline value)
        {
            obj.SetValue(OutlineProperty, value);
        }

        // Using a DependencyProperty as the backing store for Outline.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutlineProperty =
            DependencyProperty.Register("Outline", typeof(ProgressNoteOutline), typeof(OutlineBehavior),
            new FrameworkPropertyMetadata(null, OnOutlineChanged));

        private static void OnOutlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            OutlineBehavior behavior = d as OutlineBehavior;
            if (behavior == null)
                return;

            Canvas canv = behavior.AssociatedObject as Canvas;
            if (canv == null)
                return;

            ProgressNoteOutline _outline = (ProgressNoteOutline)e.NewValue;
            if (_outline == null)
                return;

            OutlineItem[] _items = _outline.items;
            foreach (OutlineItem t in _items)
            {
                TextBlock tb = new TextBlock();
                tb.Background = Brushes.AntiqueWhite;
                tb.TextAlignment = TextAlignment.Left;
                tb.Inlines.Add(new Italic(new Bold(new Run(t.text))));

                Canvas.SetLeft(tb, 0);
                Canvas.SetTop(tb, t.Y);

                canv.Children.Add(tb);
            }

        }

The RichTextBox property (in its behavior):
 public ProgressNoteOutline Outline
        {
            get { return (ProgressNoteOutline)GetValue(OutlineProperty); }
            set { SetValue(OutlineProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Outline.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutlineProperty =
            DependencyProperty.RegisterAttached("Outline", typeof(ProgressNoteOutline), typeof(RichTextBehavior),
            new FrameworkPropertyMetadata(new ProgressNoteOutline());

最后,在RichTextBox行为中,Outline被设置为:

 var _items = new OutlineItem[100];
            for (int i = 0; i < 100; i++)
            {
                _items[i] = new OutlineItem { Y = i * 30, text = string.Format("Title {0}", i) };
            }
            Outline = new ProgressNoteOutline { items = _items };

1 个答案:

答案 0 :(得分:0)

我似乎无法了解这种绑定应该如何工作 - 从一种行为到另一种行为。那么将画布子类化为:

的工作原理是什么
    public class OutlineCanvas : Canvas
    {

        public ProgressNoteOutline Outline
        {
            get { return (ProgressNoteOutline)GetValue(OutlineProperty); }
            set { SetValue(OutlineProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Outline.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutlineProperty =
                DependencyProperty.Register("Outline", 
                typeof(ProgressNoteOutline), typeof(OutlineCanvas),
                 new FrameworkPropertyMetadata(null, OnOutlineChanged));

        private static void OnOutlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            OutlineCanvas canv = d as OutlineCanvas;
            if (canv == null)
                return;           

            ProgressNoteOutline _outline = (ProgressNoteOutline)e.NewValue;
            if (_outline == null)
                return;

            OutlineItem[] _items = _outline.items;
            if (_items == null)
                return;

            foreach (OutlineItem t in _items)
            {
                TextBlock tb = new TextBlock();
                tb.Background = Brushes.AntiqueWhite;
                tb.TextAlignment = TextAlignment.Left;
                tb.Inlines.Add(new Italic(new Bold(new Run(t.text))));

                SetLeft(tb, 0);
                SetTop(tb, t.Y);

                canv.Children.Add(tb);
            }
        }
    }

然后将XAML更改为:

 <b:OutlineCanvas Grid.Column="0" x:Name="OutlineCanvas" Background="Azure" />

<b:RichTextBehavior               
       Outline="{Binding ElementName=OutlineCanvas, Path=Outline}" />

希望它有助于某人:)