好的,首先,我是Silverlight的新手,正在寻找有人提供指导,以确定以下解决方案是否是规定的解决方法。
昨天我开始研究一个乍一看似乎很简单明了的问题。我需要将承载Silverlight对象标记的ASPX代码隐藏的一些参数传递给托管的Silverlight应用程序中的一个或多个Silverlight用户控件的代码隐藏。
所以,经过一些研究,这是我开发的基本解决方案......
我发现可以将一个属性添加到名为initParams的对象标记中,可以将逗号分隔的参数名称列表和值添加到此属性中。像这样......
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/SampleApplication.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40624.0" />
<param name="autoUpgrade" value="true" />
<param name="initParams" value='DealerId=17' />
</object>
这很好,除了DealerId参数基本上在对象标签中是硬编码的,不是真正有用的。
我接下来要做的是用文字控件替换这个对象标签,并将页面代码隐藏中的文字控件文本设置为StringBuilder的值(我在其中构建了完整的对象标记)动态添加正确的DealerId值)。在下面的示例中,DealerId是硬编码的,但您明白了。
var sb = new StringBuilder();
sb.Append(@"<object data=""data:application/x-silverlight-2,"" type=""application/x-silverlight-2"" width=""90%"" height=""80%"">");
sb.Append(@"<param name=""source"" value=""ClientBin/Ascend.SilverlightViewer.xap""/>");
sb.Append(@"<param name=""onError"" value=""onSilverlightError"" />");
sb.Append(@"<param name=""background"" value=""white"" />");
sb.Append(@"<param name=""minRuntimeVersion"" value=""3.0.40624.0"" />");
sb.Append(@"<param name=""autoUpgrade"" value=""true"" />");
sb.Append(@"<param name=""initParams"" value='");
sb.Append(@"ServiceUrl=");
sb.AppendFormat("http://{0}{1}", Request.Url.Authority, ResolveUrl("~/ReportService.svc"));
sb.Append(@",DebugMode=Full");
sb.AppendFormat(@",DealerId={0}' />", 40);
sb.Append(@"</object>");
litObjectTag.Text = sb.ToString();
我的目标,如果这个初始设计是理智的,那么就是将这个对象标签创建到服务器控件中,该控件将具有DealerId属性,该属性又将在代码隐藏的主机中设置。
此时,我让主机动态地将参数值添加到object标签的initParams属性中,下一步是获取这些值并在托管的Silverlight应用程序中利用它们。
我发现了一些文章来帮助解决这个问题。我正在App.xaml.cs中创建一个公共字典,并在Application_Startup事件中设置它......
public IDictionary<string, string> InitConfigDictionary;
private void Application_Startup(object sender, StartupEventArgs e)
{
InitConfigDictionary = e.InitParams;
this.RootVisual = new MainPage();
}
现在,我可以从任何.xaml用户控件的代码隐藏中访问这个公共字典,就像这样......
App app =(App)Application.Current; var dealerId = app.InitConfigDictionary [“DealerId”];
这个设计工作正常,我只是在寻找一些指导,因为我是Silverlight的新手。再一次,实现工作,但似乎需要做很多工作才能将动态值从主机传递到.xaml文件。
因为我是Silverlight的新手,所以我希望有经验的人可以这么说:
a)帕特里克,你疯了,为什么你要完成所有这些工作,当你在Silverlight中明确地通过使用“xxxxxx”来实现这一目标时。
b)是的,帕特里克,这是一个拖累,但这个设计基本上是你在Silverlight中必须做的。再次,非常感谢任何可以提供的指导,谢谢。 - PWK
答案 0 :(得分:1)
你不需要解析我相信的全部事情。您可以从aspx页面
中按照以下方式调用代码<param name="initParams" value="<%= BuildInitParams()%>" />
在你的代码背后有
public string BuildInitParams()
{
//Dynamically build the string here;
}
希望这会有所帮助。
Rakibul
答案 1 :(得分:0)
这可能是一个古老的问题,但我记得有一个类似的问题,我只是提出了各种解决方案,至少是为了我的需要。
首先,我在.aspx页面(托管我的Silverlight应用程序)的页面后面添加了代码。在过去,我一直在将我的键/值对硬编码到initParams字段中,如下所示:
<param id="initParams" runat="server" name="initParams" value="param1=foo,param2=bar" />
我想要一个解决方案,我可以将这些值存储在配置文件中。所以我在配置文件中添加了一个带有我想要的值的部分。我清除了aspx页面上param标记中的value属性,而是使用ASPX页面中的Page_Load动态地从项目中拉取项目并在运行时将它们动态放入value属性:
protected void Page_Load(object sender, EventArgs e)
{
initParams.Attributes["value"] += "userId=" + Page.User.Identity.Name;
foreach (var key in ConfigurationManager.AppSettings.AllKeys)
{
initParams.Attributes["value"] += "," + key + "=" + ConfigurationManager.AppSettings[key];
}
}
从那里,在Silverlight应用程序的App.xaml.cs页面中,我添加了以下代码:
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
// Take parameters and store them in application resources
foreach (var data in e.InitParams)
{
this.Resources.Add(data.Key, data.Value);
}
}
加载Silverlight应用程序后,它会将它们存储在Resources对象中,然后在需要时在代码中使用以下代码引用它们:
Application.Current.Resources["param1"].ToString();
我对此的特殊用途是服务URL的端点地址。我希望这是我可以在配置文件中更改的内容,允许其他IT人员更新服务地址,而无需重建/重新部署。我可以将其硬编码到ASPX页面的initParams值属性中,但是在那里进行更改并不直观或易于阅读。我更喜欢配置文件方法。