Silverlight 在运行时更改 ControlTemplate

You cannot create a ControlTemplate in Silverlight in C# alone. Unlike WPF (where you can set the VisualTree property), there is no property you can set that specifies the "content" of the ControlTemplate.

You can define your XAML as a string, and then load that dynamically in C# as explained by this blog post.

The code boils down to:

var template = (ControlTemplate)XamlReader.Load("<ControlTemplate " +                 
       " xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"" +
       " xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">" +
       " content here " +
       "</ControlTemplate>");

这是在 stackoverflow 找到的回答。XamlReader.Load(string xaml),这个xaml有限制,不能写 x:Name ,例如“<ControlTemplate x:Name=\"ctName\",这样写运行时报错。我找到的解决办法:

建立资源文件,将需要运行时修改的设计代码写入资源文件中。例如:

<?xml version="1.0" encoding="utf-8"?>
<esri:SimpleFillSymbol
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:esri="http://schemas.esri.com/arcgis/client/2009"
                       >
    <esri:SimpleFillSymbol.ControlTemplate>
        <ControlTemplate>
            <Path x:Name="Element" Fill="Red" Stroke="White" StrokeThickness="0.4"
                              Cursor="Hand">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="SelectionStates">
                        <VisualState x:Name="Unselected">
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetName="Element"
                                                            Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" 
                                                            To="White" Duration="0:0:.25" />
                                <DoubleAnimation Storyboard.TargetName="Element" 
                                                             Storyboard.TargetProperty="StrokeThickness"
                                                             To="0.4" Duration="00:00:.25" />
                                <DoubleAnimation Storyboard.TargetName="Element" 
                                                             Storyboard.TargetProperty="Opacity"
                                                             To="0.5" Duration="00:00:.25" />
                            </Storyboard>
                        </VisualState>

                        <VisualState x:Name="Selected">
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetName="Element"
                                                            Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" 
                                                            To="Black" Duration="0:0:.25" />
                                <DoubleAnimation Storyboard.TargetName="Element" 
                                                             Storyboard.TargetProperty="StrokeThickness"
                                                             To="3" Duration="00:00:.25" />
                                <DoubleAnimation Storyboard.TargetName="Element" 
                                                             Storyboard.TargetProperty="Opacity"
                                                             To="1" Duration="00:00:.25" />
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
            </Path>
        </ControlTemplate>
    </esri:SimpleFillSymbol.ControlTemplate>
</esri:SimpleFillSymbol>

我需要运行时修改 Fill="Red" ,这个颜色。建立资源文件:ArcFill.xaml,将代码写入,设置 ArcFill.xaml 的属性:生成操作 为 嵌入的资源,以供读取使用。

技术分享

读取资源文件:

StreamReader reader = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("StMap.Resource.ArcFill.xaml"));
string strArcFill = reader.ReadToEnd();
SimpleFillSymbol sfs = XamlReader.Load(strArcFill) as SimpleFillSymbol;

资源文件文件中虽然包括了x:Name,但这样 XamlReader.Load 读取却没有任何问题。如果想改变颜色:

 XamlReader.Load(strArcFill.Replace("Red", "Green")) as SimpleFillSymbol

这样直接查找替换,工作的很 OK,红色成功变成了绿色,完整的测试用代码:

            StreamReader reader = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("StMap.Resource.ArcFill.xaml"));
            string strArcFill = reader.ReadToEnd();

            ClassBreaksRenderer newClassBreaksRenderer = new ClassBreaksRenderer();
            newClassBreaksRenderer.Field = "投诉量";

            newClassBreaksRenderer.Classes.Add(new ClassBreakInfo()
            {
                MinimumValue = 0,
                MaximumValue = 250,
                Symbol = XamlReader.Load(strArcFill.Replace("Red", "Blue")) as SimpleFillSymbol
            });

            newClassBreaksRenderer.Classes.Add(new ClassBreakInfo()
            {
                MaximumValue = 500,
                Symbol = XamlReader.Load(strArcFill.Replace("Red", "Green")) as SimpleFillSymbol
            });

            newClassBreaksRenderer.Classes.Add(new ClassBreakInfo()
            {
                MaximumValue = 750,
                Symbol = XamlReader.Load(strArcFill.Replace("Red", "Goldenrod")) as SimpleFillSymbol
            });

            PictureMarkerSymbol p = new PictureMarkerSymbol();

            newClassBreaksRenderer.Classes.Add(new ClassBreakInfo()
            {
                MaximumValue = 1000,
                Symbol = XamlReader.Load(strArcFill.Replace("Red", "DarkOrchid")) as SimpleFillSymbol
            });

            newClassBreaksRenderer.Classes.Add(new ClassBreakInfo()
            {
                MaximumValue = 9999999,
                Symbol = XamlReader.Load(strArcFill.Replace("Red", "Red")) as SimpleFillSymbol
            });

            GraphicsLayer graphicsLayer = MyMap.Layers["CY_L1"] as GraphicsLayer;
            graphicsLayer.Renderer = newClassBreaksRenderer;

 效果图:

技术分享

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。