Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何在ESRI中绑定LineSymbol上的关联菜单?_Wpf_Binding_Contextmenu_Symbols - Fatal编程技术网

Wpf 如何在ESRI中绑定LineSymbol上的关联菜单?

Wpf 如何在ESRI中绑定LineSymbol上的关联菜单?,wpf,binding,contextmenu,symbols,Wpf,Binding,Contextmenu,Symbols,我已为线条符号创建了一个ControlTemplate: <esri:SimpleLineSymbol x:Key="PolylineSymbol" Width="3" > <esri:SimpleLineSymbol.ControlTemplate> <ControlTemplate> <Grid

我已为线条符号创建了一个ControlTemplate:

            <esri:SimpleLineSymbol 
        x:Key="PolylineSymbol" 
        Width="3"
        >
        <esri:SimpleLineSymbol.ControlTemplate>
            <ControlTemplate>
                <Grid
                    >
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
    ...
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
    ...
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Path 
                        x:Name="Element" Fill="{x:Null}"
                        Stroke="Navy" StrokeThickness="3"
                                StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeEndLineCap="Round">
                        <Path.ContextMenu>
                            <ContextMenu 
                                x:Name="popUpMenu"
                                DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type esri:Graphic}}}">
                                <MenuItem 
                                    x:Name="miSelect"
                                    Header="Select" 
                                    IsCheckable="True"
                                    IsChecked="{Binding Selected, FallbackValue=False}"
                                    />
                                ...
                            </ContextMenu>
                        </Path.ContextMenu>
                    </Path>
                </Grid>
            </ControlTemplate>
        </esri:SimpleLineSymbol.ControlTemplate>
    </esri:SimpleLineSymbol>
)


有什么想法吗?

如果我正确理解了您的问题,似乎您在WPF中有一个常见的问题。解决方案是使用
路径的
标记
属性
数据上下文
传递到
上下文菜单
。获取或设置当ContextMenu打开时相对于其定位的UIElement。试试这个:

<Path x:Name="Element" Fill="{x:Null}" Stroke="Navy" StrokeThickness="3"
    StrokeLineJoin="Round" StrokeStartLineCap="Round" StrokeEndLineCap="Round"
    Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type 
    esri:Graphic}}}"><!--Use Binding.Path that you need for data here-->
    <Path.ContextMenu>
        <ContextMenu x:Name="popUpMenu" DataContext="{Binding PlacementTarget.Tag, 
            RelativeSource={RelativeSource Self}}"><!--Use PlacementTarget.Tag-->
            <MenuItem x:Name="miSelect" Header="Select" IsCheckable="True"
                IsChecked="{Binding Selected, FallbackValue=False}" />
            ...
        </ContextMenu>
    </Path.ContextMenu>
</Path>

...

解决方案是实现上下文菜单的打开偶数。在代码隐藏中,我将视图模型的实例分配给它的DataContext

    <Path.ContextMenu>
            <ContextMenu 
                    Opened="PopUpMenu_OnOpened"
            >
另一个挑战是获得点击图形和点击点。 解决方案是在视图模型中创建属性,并在LeftMouseDown和RightMouseDown上同时指定

    private Graphic GetPolylineGraphic(ESRI.ArcGIS.Client.Geometry.Geometry geometry = null)
    {
        var drawLayer = Model.GetDrawLayer(MyMap, "Polyline");
        var graphic = new Graphic
        {
            // clone the resourced PolylineSymbol (from Model)
            Symbol = new SimpleLineSymbol 
                {
                    Color = PolylineSymbol.Color,
                    Width = PolylineSymbol.Width,
                    ControlTemplate = PolylineSymbol.ControlTemplate
                }
        };

        if (geometry != null) graphic.Geometry = geometry;

        graphic.MouseLeftButtonDown += GraphicOnMouseLeftButtonDown;
        graphic.MouseRightButtonDown += GraphicOnMouseRightButtonDown;
        drawLayer.Graphics.Add(graphic);

        return graphic;
    }

    private Graphic m_clickedGraphic;
    public Graphic ClickedGraphic
    {
        get { return m_clickedGraphic; }
        set
        {
            if (!Equals(m_clickedGraphic, value))
            {
                m_clickedGraphic = value;
                OnPropertyChanged(value);
            }
        }
    }

    private MapPoint m_clickedPoint;
    public MapPoint ClickedPoint
    {
        get { return m_clickedPoint; }
        set
        {
            if (m_clickedPoint != value)
            {
                m_clickedPoint = value;
                OnPropertyChanged(value);
            }
        }
    }

    private void GraphicOnMouseRightButtonDown(object sender, MouseButtonEventArgs args)
    {
        //// This does not work because GraphicElement is internal!!!
        //var s = args.Source; 
        //ClickedGraphic = ((GraphicElement)(e.Source)).Graphic;
        //ClickedPoint = ((GraphicElement)(e.Source)).Origin;
        ClickedGraphic = sender as Graphic;
        ClickedPoint = MyMap.ScreenToMap(args.GetPosition(MyMap));

        //// not here - else context menu won't pop!
        //args.Handled = true;
    }

    private void GraphicOnMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
    {
        var g = sender as Graphic;
        if (g != null)
        {
            ClickedGraphic = g;
            ClickedPoint = MyMap.ScreenToMap(args.GetPosition(MyMap));

            // select/unselect the graphic on left click
            if (g.Selected) g.UnSelect();
            else g.Select();
            args.Handled = true;
        }
    }

为了使一切正常工作,我必须克隆符号。

在设计器中,在PlacementTarget.Tag中加上下划线,并在执行过程中出现错误“无法解析'System.Windows.UIElement'类型的数据上下文中的属性'Tag'”。我得到:System.Windows.data错误:4:无法找到与引用'RelativeSource FindAncestor'绑定的源,AncestorType='ESRI.ArcGIS.Client.Graphic',AncestorLevel='1'。BindingExpression:(无路径);DataItem=null;目标元素是'Path'(Name='element');目标属性是'Tag'(类型'Object')。我认为,这里有两个问题:1。“Path”是UIElement,它没有标记,除非我能够将其类型转换为Path。2.Path是GraphicElement的一部分,它被声明为内部,因此FindAncestor无法跨越。。。
    private void PopUpMenu_OnOpened(object sender, RoutedEventArgs e)
    {
        var menu = sender as ContextMenu;
        if (menu != null)
        {
            menu.DataContext = ViewModel;
        }
    }
    private Graphic GetPolylineGraphic(ESRI.ArcGIS.Client.Geometry.Geometry geometry = null)
    {
        var drawLayer = Model.GetDrawLayer(MyMap, "Polyline");
        var graphic = new Graphic
        {
            // clone the resourced PolylineSymbol (from Model)
            Symbol = new SimpleLineSymbol 
                {
                    Color = PolylineSymbol.Color,
                    Width = PolylineSymbol.Width,
                    ControlTemplate = PolylineSymbol.ControlTemplate
                }
        };

        if (geometry != null) graphic.Geometry = geometry;

        graphic.MouseLeftButtonDown += GraphicOnMouseLeftButtonDown;
        graphic.MouseRightButtonDown += GraphicOnMouseRightButtonDown;
        drawLayer.Graphics.Add(graphic);

        return graphic;
    }

    private Graphic m_clickedGraphic;
    public Graphic ClickedGraphic
    {
        get { return m_clickedGraphic; }
        set
        {
            if (!Equals(m_clickedGraphic, value))
            {
                m_clickedGraphic = value;
                OnPropertyChanged(value);
            }
        }
    }

    private MapPoint m_clickedPoint;
    public MapPoint ClickedPoint
    {
        get { return m_clickedPoint; }
        set
        {
            if (m_clickedPoint != value)
            {
                m_clickedPoint = value;
                OnPropertyChanged(value);
            }
        }
    }

    private void GraphicOnMouseRightButtonDown(object sender, MouseButtonEventArgs args)
    {
        //// This does not work because GraphicElement is internal!!!
        //var s = args.Source; 
        //ClickedGraphic = ((GraphicElement)(e.Source)).Graphic;
        //ClickedPoint = ((GraphicElement)(e.Source)).Origin;
        ClickedGraphic = sender as Graphic;
        ClickedPoint = MyMap.ScreenToMap(args.GetPosition(MyMap));

        //// not here - else context menu won't pop!
        //args.Handled = true;
    }

    private void GraphicOnMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
    {
        var g = sender as Graphic;
        if (g != null)
        {
            ClickedGraphic = g;
            ClickedPoint = MyMap.ScreenToMap(args.GetPosition(MyMap));

            // select/unselect the graphic on left click
            if (g.Selected) g.UnSelect();
            else g.Select();
            args.Handled = true;
        }
    }