zoukankan      html  css  js  c++  java
  • WPF后台写ControlTemplate总结

    这段时间写ControlTemplate的时候发现绑定的时候有些问题需要总结:

    实例ControlTemplate如下:

    <UserControl x:Class="ArcGISWpfMarkTest.TestSymbol"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                  xmlns:esri="http://schemas.esri.com/arcgis/client/2009"
                 xmlns:local="clr-namespace:ArcGISWpfMarkTest"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <esri:MarkerSymbol x:Key="Small" OffsetX="60" OffsetY="72">
                <esri:MarkerSymbol.ControlTemplate>
                    <ControlTemplate>
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageNormal">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageSelected">
                                                <DiscreteObjectKeyFrame KeyTime="0"  Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="label0">
                                                <DiscreteObjectKeyFrame KeyTime="0"  Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageNormal">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageSelected">
                                                <DiscreteObjectKeyFrame KeyTime="0"  Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="label0">
                                                <DiscreteObjectKeyFrame KeyTime="0"  Value="{x:Static Visibility.Visible}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="0.2*"></RowDefinition>
                                    <RowDefinition Height="0.2*"></RowDefinition>
                                    <RowDefinition Height="0.8*"></RowDefinition>
                                </Grid.RowDefinitions>
                                <Label  x:Name="label0" Visibility="Visible" Content="{Binding LabelContent1,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Grid.Row="0" BorderThickness="0.5" BorderBrush="White"  HorizontalContentAlignment="Center" Padding="0" Margin="0" Background="#2b5e93" VerticalContentAlignment="Center" Foreground="White"  Width="120" Height="20" FontSize="12"/>
                                <Label  x:Name="label1" Visibility="Visible" Content="{Binding LabelContent2,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Grid.Row="1" BorderThickness="0.5" BorderBrush="White" HorizontalContentAlignment="Center" Padding="0" Margin="0" Background="#2b5e93" VerticalContentAlignment="Center" Foreground="White" Width="120" Height="20" FontSize="12"/>
                                <Image Name="ImageNormal" Grid.Row="2" Source="/Images/small_police.png" Visibility="Visible"/>
                                <Image Name="ImageSelected" Grid.Row="2" Source="/Images/small_police_hit.png" Visibility="Hidden"/>
                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </esri:MarkerSymbol.ControlTemplate>
            </esri:MarkerSymbol>
        </UserControl.Resources>
        <Grid>
                
        </Grid>
    </UserControl>

    这个ControlTemplate是我定义的Arcgis runtime for wpf中MarkerSymbol的ControlTemplate

    首先,我遇到第一个问题是:在map窗口的主程序中调用TestSymbol这个类的实例来引用它的ControlTemplate资源时候遇到两个Label的Content无法绑定

    情况如下:TestSymbol类中我定义了LabelContent1和LabelContent2两个属性,在Map窗口的类中:

    TestSymbol testSymbol=new TestSymbol();

     testSymbol.TryFindResources("Small") as Symbol作为一个Graphic点位的Symbol,这样发现ControlTemplate定义的绑定写法其实根本就错误的。

    ControlTemplate作为资源是被Map的主窗口调用,这样它沿着可视树查找的时候的DataContext就是Map的主窗口,所以LabelContent1和LabelContent2两个属性应该定义到

    Map的主窗口类中,并且绑定应该这样写Content="{Binding LabelContent1,RelativeSource={RelativeSource AncestorType={x:Type Window}}}"

    但是这样做的话对我的程序来说没有意义,我不可能每个点位都分别定义LabelContent1和LabelContent2两个属性,所以只能另外想办法了。

    我重新定义了一个类用来存每个点位的相关信息

    using ESRI.ArcGIS.Client;
    using ESRI.ArcGIS.Client.Symbols;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    namespace ArcGISWpfMarkTest
    {
        class TestElement:Graphic
        {
            private string manName;
    
            public string ManName
            {
                get { return manName; }
                set { manName = value; }
            }
    
            private string phoneNo;
    
            public string PhoneNo
            {
                get { return phoneNo; }
                set { phoneNo = value; }
            }
            public TestElement()
            {
    
            }
            public TestElement(string ManName,string PhoneNo)
            {
                this.ManName = ManName;
                this.PhoneNo = PhoneNo;
                ImageNormal = "pack://application:,,,/Source/Images/man32.png";
                ImageSelected = "/Source/Images/man_selected32.png";
                Symbol = GetMarkerSymbol() as Symbol;
            }
    
            public MarkerSymbol GetMarkerSymbol()
            {
                MarkerSymbol markerSymbol = new MarkerSymbol();
                markerSymbol.OffsetX = 60;
                markerSymbol.OffsetY = 72;
                markerSymbol.ControlTemplate = GetControlTemplate();
                return markerSymbol;
            }
    
            public string ImageNormal { get; set; }
            public string ImageSelected { get; set; }
    
    
            private ControlTemplate GetControlTemplate()
            {
                string template = "<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'><Grid><VisualStateManager.VisualStateGroups><VisualStateGroup x:Name="SelectionStates"><VisualState x:Name="Unselected" /><VisualState x:Name="Selected"><Storyboard><ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageNormal"><DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="ImageSelected"><DiscreteObjectKeyFrame KeyTime="0"  Value="{x:Static Visibility.Visible}"/></ObjectAnimationUsingKeyFrames></Storyboard></VisualState></VisualStateGroup></VisualStateManager.VisualStateGroups><Grid><Grid.RowDefinitions><RowDefinition Height="0.2 * "></RowDefinition><RowDefinition Height="0.2 * "></RowDefinition><RowDefinition Height="0.8 * "></RowDefinition></Grid.RowDefinitions><Label Visibility="Visible" Grid.Row="0" BorderThickness="0.5" BorderBrush="White"  HorizontalContentAlignment="Center" Padding="0" Margin="0" Background="" + "#2b5e93" + "" VerticalContentAlignment="Center" Foreground="White" Content="" + ManName + "" Width="" + "120" + "" Height="" + "20" + "" FontSize="" + "12" + ""/><Label Visibility="Visible" Grid.Row="1" BorderThickness="0.5" BorderBrush="White" HorizontalContentAlignment="Center" Padding="0" Margin="0" Background="" + "#2b5e93" + "" VerticalContentAlignment="Center" Foreground="White" Content="" + PhoneNo + "" Width="" + "120" + "" Height="" + "20" + "" FontSize="" + "12" + ""/><Image Name="ImageNormal" Grid.Row="2" Source="" + ImageNormal + "" Visibility="Visible"/><Image Name="ImageSelected" Grid.Row="2" Source="" + ImageSelected + "" Visibility="Hidden"/></Grid></Grid></ControlTemplate>";
                var tem = XamlReader.Parse(template);
                return tem as ControlTemplate;
            }
        }
    }
    

      这个TestElement类的关键思想是把xmal代码定义成字符串格式,然后这个字符串是依赖于TestElement类的自身属性而动态生成的,不同实例传入的属性不同,所以突破了xmal绑定机制的限制,可以成功的为每个点位传入不同的属性值了,这个xmal代码字符串通过以下代码成功转为ControlTemplate了。

     var tem = XamlReader.Parse(template);
                return tem as ControlTemplate;

    以上做法有点违背wpf思想设计初衷,我也是没办法才如此做的,谁叫我的WPF技能不够高呢。。


    在查找使用C#代码后台定义ControlTemplate的时候,发现这篇博文的方法也可行,只是再写布局的时候有些麻烦,我暂时还没有去实现
    http://blog.csdn.net/zyloveyrf/article/details/6736844

    还有一个问题总结:
    在写Image的资源路径的时候遇到这样一个问题:
    在Demo程序中这样定义Image的Resource可行

     "pack://application:,,,/Source/Images/man32.png" 绝对路径
     "/Source/Images/man_selected32.png" 相对路径

    但是有时候上面的写法无效,非要下面的写法才行:

    "pack://application:,,,/SDGPS_ManLayer;component/Source/Images/man32.png";
    "pack://application:,,,/SDGPS_ManLayer;component/Source/Images/man_selected32.png";

    这种情况发生在我的图层是单独编译成一个DLL,与MAP的主程序分离设计的。

    我想可能是程序资源集引用的相关问题,以后再做研究。

    WPF的Resource路径参考:

    http://www.cnblogs.com/kushisei/p/5747708.html

    https://msdn.microsoft.com/library/aa970069(v=vs.100).aspx

    挂两个外链,管理员请不要删我文,如违规可联系我自行删除,QQ:919497132

    苏州空调维修 苏州冰箱维修 上海注册公司

  • 相关阅读:
    ios qq 分享 失败
    Collections在sort()简单分析法源
    C# char[]与string之间的相互转换
    uva 10837
    良好的互联网站点
    SVN库迁移
    Android 它们的定义View它BounceProgressBar
    #AOS应用基础平台# 添加了用户自己定义快捷菜单在平铺布局下的用户自己定义排序管理
    android 逆向project smail 语法学习
    Linux内核-系统调用
  • 原文地址:https://www.cnblogs.com/lelehellow/p/7278860.html
Copyright © 2011-2022 走看看