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
WPF后台写ControlTemplate总结的更多相关文章
- WPF后台设置xaml控件的样式System.Windows.Style
WPF后台设置xaml控件的样式System.Windows.Style 摘-自 :感谢 作者: IT小兵 http://3w.suchso.com/projecteac-tual/wpf-zhi ...
- WPF 后台C#设置控件背景图片
原文:WPF 后台C#设置控件背景图片 以前的程序中有做过,当时只是记得uri很长一大段就没怎么记.今天有人问了也就写下来. 这是一个Button,设置了Background后的效果. 前台的设置 ...
- WPF 后台获得 数据模板里的内容控件(DataTemplate)
原文:WPF 后台获得 数据模板里的内容控件(DataTemplate) 假如 <Window.Resources> 里 有一个 Datatemplate 我想获得TextBlo ...
- C# WPF后台动态添加控件(经典)
概述 在Winform中从后台添加控件相对比较容易,但是在WPF中,我们知道界面是通过XAML编写的,如何把后台写好的控件动态添加到前台呢?本节举例介绍这个问题. 这里要用到UniformGrid布局 ...
- WPF中的ControlTemplate(控件模板)(转)
原文地址 http://www.cnblogs.com/zhouyinhui/archive/2007/03/28/690993.html WPF中的ControlTemplate(控件模板) ...
- WPF后台访问XAML元素
当我们需要从后台访问xaml文件时,我们可以通过这样的方式来操作: private void button1_Click(object sender, RoutedEventArgs e) { Sys ...
- excel导出的时候从程序后台写到excel里的是文本,所以无法在excel中计算怎么办?
文章引用自:http://www.cnblogs.com/rayray/p/3414452.html excel导出的时候从程序后台写到excel里的是文本,所以无法在excel中计算怎么办? 需要导 ...
- wpf后台设置颜色(背景色,前景色)
有时候你是不是也会遇到要在wpf后台给某个控件设置背景色或者给文字设置前景色的情况? 本人最近看到一个从自定义的combobox读取系统字体和颜色的实例,该实例实现了随字体combobox选项改变而改 ...
- WPF中的ControlTemplate(控件模板)
原文:WPF中的ControlTemplate(控件模板) WPF中的ControlTemplate(控件模板) ...
随机推荐
- 【转】Visual Studio Code 使用Git进行版本控制
原文链接:https://www.cnblogs.com/xuanhun/p/6019038.html?utm_source=tuicool&utm_medium=referral 本来认为此 ...
- 《Linux命令行与shell脚本编程大全》第二十六章 一些有意思的脚本
26.1 发送消息 26.1.1 功能分析 1.确定系统中都有谁 $who 给出的信息包括用户名 用户所在终端 用户登入系统的时间 2.启用消息功能 用户可以禁止别人给我发消息,所以需要先检查一下是否 ...
- 了解web及网络基础
了解web及网络基础 以下内容简单的说明了一下TCP/IP协议族中HTTP协议.DNS服务.IP协议的一些概念和关系.笔者只是对知识点进行了总结,仅供参考: ) 转载请注明出处:了解web及网络基础 ...
- Nodejs学习笔记(十七)--- 浮点运算decimal.js
目录 前言 JavaScript加减乘除运算 decimal.js加减乘除运算 前言 开发过程中免不了有浮点运算,JavaScript浮点运算的精度问题会带来一些困扰 JavaScript 只有一种数 ...
- PF_RING install in centos7
很多centos7是最小化安装. 这样很多kernel就没有安装全,而且很多开发库也没有. 在安装PF_RING过程中,会缺少很多依赖. 首先安装依赖包: yum -y install numactl ...
- layui使用心得
表单控件样式没生效, 因为没引入form. layui.use('form', function(){ var form = layui.form; }); radio改变事件没生效, 需要手动fil ...
- .NET Core 快速入门教程
.NET Core 快速学习.入门系列教程.这个入门系列教程主要跟大家聊聊.NET Core的前世今生,以及Windows.Linux(CentOS.Ubuntu)基础开发环境的搭建.第一个.NET ...
- 初识java这个小姑娘(三)
说烂了的面向对象 我要说的面向对象,其实是一个我自己都觉的有点恶心的东西. 它是java语言入门如此初级的一个概念.作为一个老鸟,你可以吐口水给我,我可以把它们擦干,但作为总结还得说一说. 因为对于一 ...
- zeppelin0.7.3源码编译
操作系统: Centos7.X Python版本: Python2.7 Maven版本:3.1.* Git:1.8.3.* JAVA:java1.7+ node npm bower grunt 每次执 ...
- C#中的Explicit和Implicit
今天在Review一个老项目的时候,看到一段奇怪的代码. if (dto.Payment == null) continue; var entity = entries.FirstOrDefault( ...