#javascript #silverlight-4.0 #silverlight-toolkit
#javascript #silverlight-4.0 #silverlight-toolkit
Вопрос:
У меня есть элемент управления silverlight, в котором есть фрейм. Я хочу изменить URI этого фрейма из-за пределов элемента управления SL. (У меня есть HTML-ссылка, которая будет использовать Javascript, чтобы автоматически указать элементу управления SL на изменение.) Все это работает, но я получаю случайные ошибки JavaScript.
Главная страница:
<html>
<body>
<a href="#" onclick="PdmcNav.NavigateTo('page1');">Page 1 Link</a>
<a href="#" onclick="PdmcNav.NavigateTo('page2');">Page 2 Link</a>
<div id="main" >
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</body>
</html>
Включен Javascript:
// Defining the namespace object for the Pdmc navigation
var PdmcNav = {};
PdmcNav.PdmcSLControl = null;
PdmcNav.NavigateTo = function (pagename) {
// check to see if PDMC Silverlight control is on page. if not (is null), then need to load main PDMC page
if (PdmcNav.PdmcSLControl == null) {
// handle this later
} else {
// Pdmc SL control on page..
// Talk to silverlight control and request it to navigate to pagename
PdmcNav.PdmcSLControl.Content.PdmcSL.NavigateToPage(pagename);
}
}
Главная страница Xaml загружается на главную страницу (MainNavigationView.xaml)
<UserControl x:Class="PDMC.Views.MainNavigationView"
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:toolkit="clr-namespace:Microsoft.Windows;assembly=System.Windows.Controls.Toolkit"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:navigationCore="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
mc:Ignorable="d">
<StackPanel>
<!-- this is a test of navigation in the control.... works flawlessly -->
<StackPanel Orientation="Horizontal">
<HyperlinkButton Content="profile" Margin="4" TargetName="contentFrame" NavigateUri="/Views/SupplierProfile.xaml"/>
<HyperlinkButton Content="scores" Margin="4" TargetName="contentFrame" NavigateUri="/Views/SupplierScores.xaml"/>
</StackPanel>
<navigation:Frame x:Name="contentFrame"
Source="/Views/Profile.xaml"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</StackPanel>
</UserControl>
MainNavigationView.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Browser;
using System;
namespace PDMC.Views {
public partial class MainNavigationView : UserControl {
/// <summary>
/// Initializes a new instance of the MainNavigationView class.
/// </summary>
public MainNavigationView() {
InitializeComponent();
HtmlPage.RegisterScriptableObject("PdmcSL", this);
}
[ScriptableMember]
public void NavigateToPage(string pageName) {
if (pageName == "Profile") {
Uri x = new Uri(@"/Views/Profile.xaml", System.UriKind.RelativeOrAbsolute);
contentFrame.Source = x;//.Navigate(x);
} else if (pageName == "Scores") {
Uri x = new Uri(@"/Views/Scores.xaml", System.UriKind.RelativeOrAbsolute);
contentFrame.Source=x;//.Navigate(x);
}
}
}
}
Я могу щелкнуть по ссылкам на главной странице несколько раз, но после нескольких переходов туда и обратно я получаю следующую ошибку: (она случайна, когда я получаю это)
Message: Unhandled Error in Silverlight Application Content for the URI cannot be loaded. The URI may be invalid.
Parameter name: uri at System.Windows.Navigation.NavigationService.NavigateCore(Uri uri, NavigationMode mode, Boolean suppressJournalAdd, Boolean isRedirect)
at System.Windows.Navigation.NavigationService.Journal_Navigated(Object sender, JournalEventArgs args)
at System.Windows.Navigation.Journal.OnNavigated(String name, Uri uri, NavigationMode mode)
at System.Windows.Navigation.Journal.UpdateObservables(JournalEntry currentEntry, NavigationMode mode)
at System.Windows.Navigation.Journal.AddHistoryPoint(JournalEntry journalEntry)
at System.Windows.Navigation.Journal.AddHistoryPointIfDifferent(String newState)
at System.Windows.Navigation.Journal.Browser_Navigated(Object sender, EventArgs eventArgs)
at System.Windows.Navigation.Journal.<>c__DisplayClass3.<InitializeNavigationState>b__2(Object sender, NavigationStateChangedEventArgs args)
at System.Windows.Interop.SilverlightHost.RaiseNavigationStateChanged(String oldState, String newState)
at System.Windows.Interop.SilverlightHost.OnNavigationStatePollingTick(Object sender, EventArgs e)
at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
Кто-нибудь видит, что я делаю не так?
Ответ №1:
Похоже, что решение моей проблемы заключается в изменении моего подхода. В ходе моего исследования я обнаружил, что для Frame
элемента в Main.xaml по умолчанию JournalOwnership
установлено значение Automatic
. Если я установлю для этого значение OwnsJournal
, проблема исчезнет. По-видимому, если фрейм использует журнал браузера, при переходе через [ScriptableMethod]
происходят странные вещи.
Моим решением было изменить мой подход к проблеме …. который в конечном итоге стал более простым и элегантным. Следует отметить, что когда Журнал управляется браузером ( JournalOwnership=Automatic
), вы можете переходить к страницам в пределах вашего элемента управления, просто используя URL.
Вот решение, к которому я пришел, которое позволяет мне иметь HTML-навигацию (вне моего элемента управления silverlight), которая будет переходить к разным страницам в моем элементе управления SL.
Главная страница (обычный Html со ссылками на навигацию)
<html>
<body>
<asp:HyperLink ID="HyperLink4" runat="server" NavigateUrl="~/PDMC.aspx#Profiles">Profiles</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="~/PDMC.aspx#Scores">Scores</asp:HyperLink>
</body>
</html>
Обратите внимание, PDMC.aspx — это простая страница, которая содержит мой объект управления silverlight.
Main.xaml является корневым интерфейсом моего элемента управления silverlight. Он просто содержит фрейм, который мы будем использовать для замены представлений:
<navigation:Page x:Class="PDMC.Views.Main"
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"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="640" d:DesignHeight="480"
Title="Main Page">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<StackPanel x:Name="LayoutRoot">
<navigation:Frame x:Name="MainFrame"
Source="/Views/Profile.xaml"
JournalOwnership="Automatic"
UriMapper="{StaticResource PDMC_UriMapper}" />
</StackPanel>
</ScrollViewer>
</navigation:Page>
Наконец, чтобы сделать внешние ссылки проще и красивее, я добавил UriMapper в свое приложение.xaml:
<Application.Resources>
<navigationCore:UriMapper x:Key="PDMC_UriMapper">
<navigationCore:UriMapping Uri="Profiles" MappedUri="/Views/Profile.xaml" />
<navigationCore:UriMapping Uri="Scores" MappedUri="/Views/Scores.xaml" />
</navigationCore:UriMapper>
</Application.Resources>
Вот и все .. гораздо более простое решение.. Надеюсь, это поможет кому-то еще в будущем (и да, я новичок в silverlight на момент этого открытия :))
Комментарии:
1. У меня тоже есть требования аналогичного рода. У меня тоже есть фрейм в моем Main. Xaml (я назвал его «abc») Вот как я создаю объект silverlight. Silverlight.CreateObject( «ClientBin/InSite. Shell.xap», // исходный документ.getElementById(‘silverlightControlHost’), // родительский элемент «insiteSilverLight», // идентификатор сгенерированного элемента объекта { ширина: «100%», высота: «100%», фон: «белый», версия: «4.0.60310.0» }, { Загрузка: onSLLoad } );
2. Я получаю отправителя загруженного события. я хочу вызвать функцию onSLLoad(sender, EventArgs) { var rootFrame = sender.children[0]; } . Перейдите к (‘#my/path’) в этом фрейме. Но я не могу. Как мне получить тип дочернего элемента. Он просто возвращается как HtmlParamElement, и я не могу быть уверен, тот ли это фрейм, который я запрашиваю. Как мне проанализировать DOM и выполнить метод NavigateTo()?