Dynamicznie zmieniaj rozmiar kontrolki Silverlight na stronie internetowej

Oto kwestia...

Dodaję pewne kontrolki Silverlight 3 do aplikacji ASP.Net Web Forms. Wysokość aplikacji Silverlight może się zmieniać w zależności od ilości zawartych w niej danych. Aplikacja jest częścią strony internetowej, a nie całą stroną. Moi użytkownicy chcieliby mieć tylko 1 zestaw pasków przewijania. Czy istnieje sposób na dynamiczne zmienianie rozmiaru elementu div lub obiektu w oparciu o wielkość aplikacji Silverlight?

Czy mogę na przykład podłączyć się do JavaScriptu Silverlight, aby to jakoś zrobić?


person Gus    schedule 14.12.2009    source źródło


Odpowiedzi (3)


Można to zrobić na dwa sposoby: albo uzyskując bezpośredni dostęp do elementu DOM i zmieniając jego atrybuty stylu (lub css), albo wywołując na stronie funkcję JavaScript, która zrobi to samo. Poniżej mam kod xaml, kod i kod HTML prostego przykładu, który po przeciągnięciu suwaka w kontrolce Silverlight zmienia rozmiar elementu div zawierającego kontrolkę. Jeśli utworzysz prostą aplikację Silverlight z uzupełniającą witryną testową i stroną testową, a następnie skopiujesz i wkleisz następujący kod, możesz się pobawić (pamiętaj, że dla dobra strony wyciąłem część wygenerowanych stylów/skryptów ze strony aspx zwięzłości).

Kod C# i JavaScript nie jest szczególnie ładny ani kuloodporny, to po prostu przykład.

<UserControl x:Class="SilverlightApplication6.MainPage"
    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" d:DesignWidth="200" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">

      <Slider x:Name="WidthSlider" Value="50" Maximum="200"></Slider>

  </Grid>
</UserControl>

Kod odpowiedzialny za aplikację Silverlight:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        WidthSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(WidthSlider_ValueChanged);
    }

    private void WidthSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        //access and manipulate the DOM element directly:
        HtmlElement container = HtmlPage.Document.GetElementById("silverlightControlHost");
        if (container != null)
        {
            container.SetStyleAttribute("width", (50 + e.NewValue).ToString() + "px");
        }

        //pass a delta value to the js function, which will get added to the current width of the container:
        HtmlPage.Window.Invoke("resizeContainer", (e.NewValue - e.OldValue).ToString());
    }
}

i strona aspx:

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>SilverlightApplication6</title>
    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript">
        function resizeContainer(delta) {
            var container = document.getElementById('silverlightControlHost');
            if (container != null) {
                //alert('starting width: ' + container.style.width);
                container.style.width = (parseInt(container.style.width) + Number(delta) + 'px');
                //alert('finishing width: ' + container.style.width);
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server" style="height:100%">
    <div id="silverlightControlHost" style="border: solid 1px red; width:200px; height: 400px;">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
          <param name="source" value="ClientBin/SilverlightApplication6.xap"/>
          <param name="onError" value="onSilverlightError" />
          <param name="background" value="white" />
          <param name="minRuntimeVersion" value="3.0.40624.0" />
          <param name="autoUpgrade" value="true" />
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
          </a>
        </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
    </form>
</body>
</html>

Edycja: Dwa dni po napisaniu tej odpowiedzi Charles Petzold napisał post na blogu na temat zmiany rozmiaru elementów sterujących Silverlight na stronie HTML, znajdziesz je tutaj. Główna różnica polega na tym, że on zmienia rozmiar rzeczywistej kontrolki wtyczki Silverlight, podczas gdy ja zmieniam rozmiar elementu HTML, w którym znajduje się wtyczka Silverlight.

person slugster    schedule 16.12.2009

Robię coś podobnego z kontrolką Silverlight, którą zrobiłem. Mój problem polegał na tym, że miałem kontrolę umożliwiającą pokazywanie skanów dokumentów w kontrolce Silverlight i wysokość miałem zakodowaną na stałe, ale niektórzy użytkownicy używali znacznie wyższej rozdzielczości, więc mieli dużo zmarnowanego miejsca, które mogli wykorzystać.

Zaimplementowałem więc małą funkcję JavaScript po stronie klienta, która określa optymalny rozmiar kontrolki. Ten kod działa podczas ładowania strony.

Na dole strony HTML dodaj następujący kod (używając Jquery):

<script type="text/javascript" language="javascript">
    function InitializeSilverlightControlHeight()
    {
        $(function()
        {
            var miniumimControlSize = 500;
            var pagePadding = 150;
            var screenheight = $(window).height() - pagePadding;
            if (screenheight > miniumimControlSize)
            {
                $("#yourSilverLightControlName").height(screenheight);
            }
        });
    }

    InitializeSilverlightControlHeight();
</script>

Powoduje to sprawdzenie widocznego rozmiaru okna przeglądarki, a następnie odejmowanie wartości dopełnienia (która w moim przypadku wynosi 150 pikseli, aby uwzględnić wysokość nagłówka). Jeśli ten rozmiar jest większy niż minimalny rozmiar kontrolki, ustawia kontrolkę na ten rozmiar.

Mam nadzieję, że to pomoże lub przynajmniej wskaże ogólny kierunek, w którym będziesz mógł się poruszać.

person Kelsey    schedule 15.12.2009
comment
Jednak nie do końca to, czego szukałem, dziękuję. Moi użytkownicy chcą, aby kontrolka Silverlight zawsze się powiększała i przewijała tylko za pomocą pasków przewijania przeglądarki. Muszę więc uzyskać wysokość aplikacji SL i jakoś przekazać ją do przeglądarki. - person Gus; 15.12.2009

Nie sądzę, że to jest dokładnie to, czego szukasz, ale może pomóc...

W aktorze pierwszej strony utworzonej przez kontrolkę Silverlight możesz dodać wydarzenie

App.Current.Host.Content.Resized += new EventHandler(Content_Resized);

Następnie w detektorze zdarzeń możesz zmienić rozmiar kontrolki, aby lepiej dopasować ją do okna.

void Content_Resized(object sender, EventArgs e)
{
    double height = App.Current.Host.Content.ActualHeight;
    double width = App.Current.Host.Content.ActualWidth;
    this.Height = height;
    this.Width = width;
    m_currentPage.Height = height;
    m_currentPage.Width = width;
} 

Mam nadzieję, że to pomoże =D

person Ragepotato    schedule 15.12.2009