1

精简问题:在 WPF 样式中,如何访问正在设置样式的对象的数据中的属性?

style  ----- this access--------
   UI object                   |
      data                     |
        property{get;set;} <-- | Access this
      /data
   /UI object
/style

我有一个 ItemsControl,它显示了一堆多边形。

代码:

<ItemsControl x:Name="TopVectorItemControl" Grid.Row="1" ItemsSource="{Binding TopVectorData}"
            SizeChanged="TimelineItemsControl_SizeChanged" MouseRightButtonUp="TimelineItemControl_MouseRightButtonUp">
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Common:ZoomableCanvas x:Name="TopAxis" Background="#FF65656C" Grid.Row="1" AllowDrop="True" IsVirtualizing="False"/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <ContentControl MouseDoubleClick="Polygon_DoubleClicked">
            <Polygon Points="{Binding Points, Converter={StaticResource PointsConverter}}" Tag="{Binding Tag}" Stroke="Black" 
                        Fill="{Binding DirectionProp, Converter={StaticResource FillConverterTopBottomAxis}}" />
        </ContentControl>
    </DataTemplate>
</ItemsControl.ItemTemplate>

当用户双击多边形时,我会应用一种样式(这些是多边形上每个点的装饰器)以允许用户更改多边形的形状/大小)。

款式代码:

<Style x:Key="ThumbStyleLeft" TargetType="{x:Type Thumb}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Thumb}">
            <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Width="21">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="12"/>
                    <ColumnDefinition Width="1*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="8"/>
                    <RowDefinition Height="10"/>
                </Grid.RowDefinitions>
                <Ellipse Width="8" Height="8" Stroke="Black" StrokeThickness="1"  Grid.Row="1" Grid.Column="1" 
                            Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1,1,0,0">
                    <Ellipse.Fill >
                        <SolidColorBrush Color="Blue" Opacity=".5"></SolidColorBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Label Content="000" Grid.Column="0" FontFamily="Segoe UI Semibold" FontSize="7" Foreground="Black" Padding="0" />
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

图片: 在此处输入图像描述

而不是“000”,我需要设置标签的内容

<Label Content="000" Grid.Column="0" FontFamily="Segoe UI Semibold" FontSize="7" Foreground="Black" Padding="0" />

在样式中,属性:

public String TestingLabel {get;set;}

它与我的多边形绑定到“点”的类和级别相同

<Polygon Points="{Binding Points, Converter={StaticResource PointsConverter}}" Tag="{Binding Tag}" Stroke="Black" Fill="{Binding DirectionProp, Converter={StaticResource FillConverterTopBottomAxis}}" />

我该怎么做呢?

我试过了:

{模板绑定测试标签}

{绑定路径=TestingLabel,RelativeSource={RelativeSource Self}}

没有成功。

这是我将样式添加到拇指的代码:

public class AxisSelectionAdorners : Adorner
{
    private readonly Grid timelineGrid;
    private readonly ArrayList thumbArrray;
    private readonly TimelineItem timelineItem;
    private readonly VisualCollection visualChildren;

    public AxisSelectionAdorners(UIElement adornedElement, TimelineItem elementAt, Grid grid)
        : base(adornedElement)
    {
        thumbArrray = new ArrayList();
        visualChildren = new VisualCollection(this);

        timelineItem = elementAt;
        this.timelineGrid = grid;

        attachAdorners((Polygon)adornedElement);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        var adornedElement = this.AdornedElement as FrameworkElement;

        var polygon = (Polygon)adornedElement;
        var p = new Point();
        if (polygon != null)
        {
            Thumb thumb;
            for (int i = 0; i < polygon.Points.Count; i++)
            {
                p = polygon.Points[i];
                thumb = (Thumb)thumbArrray[i];
                if ((i == (int)TagId.Start) || (i == (int)TagId.FadeInEnd) || (i == (int)TagId.FadeInMag))
                {
                    thumb.Arrange(new Rect(p.X - 17, p.Y - 16, 22, 25));
                }
                else if ((i == (int)TagId.End) || (i == (int)TagId.FadeOutMag) || (i == (int)TagId.FadeOutStart))
                {
                    thumb.Arrange(new Rect(p.X - 5, p.Y - 16, 20, 25));
                }
                else
                {
                    thumb.Arrange(new Rect(p.X - 5, p.Y - 5, 10, 10));
                }
            }
            p.X = (polygon.Points[(int)TagId.End].X - polygon.Points[(int)TagId.Start].X) / 2;
            p.X += polygon.Points[(int)TagId.Start].X;
            p.Y = polygon.Points[(int)TagId.FadeInEnd].Y;

            thumb = (Thumb)thumbArrray[polygon.Points.Count];
            thumb.Arrange(new Rect(p.X, p.Y, 14, 17));

            p.X += 15;
            thumb = (Thumb)thumbArrray[polygon.Points.Count+1];
            thumb.Arrange(new Rect(p.X, p.Y, 15, 9));
        }
        return finalSize;
    }

    private void BuildCorner(ref Thumb thumb, Cursor tempCursor, int id)
    {
        thumb.Height = 20;
        thumb.Width = 30;

        thumb.Cursor = tempCursor;
        Style style;
        if (id == (int)TagId.Direction)
        {
            // build style in code so we can bind the mouse click
            thumb.Height = 30;

            var s =new Style();

            var grid = new FrameworkElementFactory(typeof(Grid));

            var label = new FrameworkElementFactory(typeof(Label));

            label.SetValue(Label.ContentProperty, "<>");
            label.SetValue(Label.FontSizeProperty, 9d);
            label.SetValue(Label.PaddingProperty, new Thickness(0));
            label.SetValue(Label.FontFamilyProperty, new FontFamily("Verdana"));
            label.AddHandler(MouseLeftButtonDownEvent,  new MouseButtonEventHandler(DirectionThumbClick));

            grid.AppendChild(label);

            var ct = new ControlTemplate(typeof(Thumb)) { VisualTree = grid };

            s.Setters.Add(new Setter(MainWindow.TemplateProperty, ct));
            style = s;

        }
        else
        {
            if ((id == (int)TagId.Start) || (id == (int)TagId.FadeInEnd) || (id == (int)TagId.FadeInMag))
            {
                style = (Style)Application.Current.Resources["ThumbStyleLeft"];
            }
            else if (id == (int)TagId.Middle)
            {
                thumb.Height = 17;
                thumb.Width = 14;
                style = (Style)Application.Current.Resources["ThumbStyle"];
            }
            else
            {
                style = (Style)Application.Current.Resources["ThumbStyleRight"];
            }
        }
        thumb.Style = style;
        thumb.Opacity = 0.80;

        visualChildren.Add(thumb);
    }

    private void attachAdorners(Polygon polygon)
    {
        for (int i = 0; i <= polygon.Points.Count+1; i++)
        {
            var p = new Point();
            var thumb = new Thumb();
            Cursor tempCursor = null;

            if (i < polygon.Points.Count)
            {
                p = polygon.Points[i];
            }

            switch (i)
            {
                case (int)TagId.Start:
                case (int)TagId.End:
                    tempCursor = Cursors.SizeWE;
                    break;
                case (int)TagId.FadeOutStart:
                case (int)TagId.FadeInEnd:
                    tempCursor = Cursors.SizeNWSE;
                    break;
                case (int)TagId.FadeOutMag:
                case (int)TagId.FadeInMag:
                    tempCursor = Cursors.SizeNS;
                    break;
                case (int)TagId.Middle:
                    tempCursor = Cursors.Hand;
                    break;
                case (int)TagId.Direction:
                    tempCursor = Cursors.Arrow;
                    thumb.MouseRightButtonDown += this.DirectionThumbClick;
                    break;
            }

            BuildCorner(ref thumb, tempCursor, i);

            thumb.Tag = i;
            thumb.DragDelta += this.ThumbDragDelta;
            thumb.MouseEnter += this.ThumbOnMouseEnter;

            thumbArrray.Add(thumb);
        }
    }
 }

这是我将拇指(装饰器)附加到多边形的代码:

private void Polygon_DoubleClicked(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource is Shape)
{
    UIElement uie = (UIElement)e.OriginalSource;
    Polygon p = e.OriginalSource as Polygon;

    if (p != null)
    {
        var tag = p.Tag as TimelineTag;
        //TimelineCollection is an ObservableCollection<>
        TimelineCollection collection = this.GetCollectionBasedOnTagLevel(tag);

        if (tag != null && ((TimelineItem)collection.ElementAt(tag.Id)).IsEditing)
        {
            AdornerLayer adornerlayer = AdornerLayer.GetAdornerLayer(uie);

            p.Stroke = new SolidColorBrush(Color.FromRgb(000, 000, 000));
            Adorner[] toRemoveArray = adornerlayer.GetAdorners(uie);
            if (toRemoveArray != null)
            {
                for (int x = 0; x < toRemoveArray.Length; x++)
                {
                    adornerlayer.Remove(toRemoveArray[x]);
                }
            }
            ((TimelineItem)collection.ElementAt(tag.Id)).IsEditing = false;
            selectedPolygon = null;
        }
        else
        {
            if (tag != null)
            {
                if (((TimelineItem)collection.ElementAt(tag.Id)).Type == TimelineItem.TimelineItemType.Axis)
                {
                    var sel = new AxisSelectionAdorners(
                        uie, (TimelineItem)collection.ElementAt(tag.Id), this.TimelineGrid);
                    p.Stroke = new SolidColorBrush(Color.FromRgb(255, 255, 255));

                    AdornerLayer adornerlayer = AdornerLayer.GetAdornerLayer(uie);
                    adornerlayer.Add(sel);
                }
                else if (((TimelineItem)collection.ElementAt(tag.Id)).Type
                            == TimelineItem.TimelineItemType.Square)
                {
                    var sel = new SquareSelectionAdorners(
                        uie, (TimelineItem)collection.ElementAt(tag.Id), this.TimelineGrid);
                    p.Stroke = new SolidColorBrush(Color.FromRgb(255, 255, 255));

                    AdornerLayer adornerlayer = AdornerLayer.GetAdornerLayer(uie);
                    adornerlayer.Add(sel);
                }
                ((TimelineItem)collection.ElementAt(tag.Id)).IsEditing = true;
                selectedPolygon = p;
            }
        }
    }
}
}
4

1 回答 1

0

好吧,这不是一个完整的答案,但它符合我的需求。

我不需要深入研究多边形的数据,因为这些值不是数据值,它们是计算值。它们不需要在我的“数据层”中,它们可以是我的装饰类中的计算值。

我通过把

public String TestingLabel { get { return "test"; } }

在我的AxisSelectionAdorners课堂上。然后像这样与 xaml 绑定:

{Binding TestingLabel, RelativeSource={RelativeSource AncestorType={x:Type Timeline:AxisSelectionAdorners}}}

这是测试代码,可以根据需要连接转换器等。

于 2012-11-27T02:25:02.540 回答