顯示具有 Sliverlight 標籤的文章。 顯示所有文章
顯示具有 Sliverlight 標籤的文章。 顯示所有文章

Silverlight//XAML物件的事件觸發 vs CS的函數

沒有留言:
在Silverlight中,function和XAML的互動物件,似乎是沒有直接關係的,也就是說,如果你沒有依照下面這樣做,你的Silverlight就是一堆介面元件與function而已,它們互不認識唷。

Silverlight說方便是不方便,說難也不難。怎麼說呢?我們現在要講的,竟然有很多方式可以完成。在此講兩個方式,我覺得比較簡單,而且適用於不同取向的設計者。

第一種方式,適合給做視覺的網頁設計師。

*.XAML檔

在XAML,介面物件與物件的事件要觸發的function註冊在一起了。

    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <Button Name="cmdClickMe" Content="ClickMe!" Margin="5" Click="cmdClickMe_Click"/>
        </StackPanel>
    </Grid>

*.cs檔

在cs,只要對物件的行為做定義即可。不需也無法修改什麼物件要觸發什麼function。
namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        int i = 0;
        private void cmdClickMe_Click(object sender, RoutedEventArgs e)
        {
            cmdClickMe.Content = "this is " + i++;
        }

    }
}

第二種方式,適合給做介面的程式設計師。


*.xaml檔

在XAML,只有定義介面的物件名稱。
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <Button Name="cmdClickMe" Content="ClickMe!" Margin="5"/>
        </StackPanel>
    </Grid>

*.cs檔

在cs才定義該物件的行為,什麼事件會觸發什麼function
namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            cmdClickMe.Click += cmdClickMe_Click;  //委派 XamlFunction = Csfunction

        }

        int i = 0;
        private void cmdClickMe_Click(object sender, RoutedEventArgs e)
        {
            cmdClickMe.Content = "this is " + i++;
        }

    }
}
我自己覺得第二種比較適合我,給大家參考看看。
個人的見解,寫下這一段之前,還沒有拜讀任何大師的作品,所以不要太相信呀。
因為,XAML與cs檔之間,畢竟還是有彈性上的差異。XAML上屬靜態定義,在CS上屬動態定義,善用程式碼做動態的變化,在頁面呈現給使用者看之後,還可以保留對介面物件的事件與CS函數的委派關係做修改的空間。

最後,兩個方法都使用會怎樣?
也就是,在XAML註冊了,也在CS中用了委派。那會執行兩次?還是視為一次執行?
試完的結果是,執行兩次。XDDD

Silverlight//像html的CSS功能

沒有留言:
CSS之於HTML那麼,XML:STYLE就之於XML

用Silverlight的說法,將style設定成全域的寫法,用html的表示如下:

mystyle.css檔

body{ margin-top:10px}

*.html檔

<html>
<head>
    <title>Google</title>
    <link rel="stylesheet" href="mystyle.css">
</head>
<body>

</body>
</html>
用xml的表示如下:
在Silverlight中Body並非預設標籤,只是要和HTML做對照而舉的例子而已。
可以用內建標籤取代之,例如<Button>之類的。

App.xaml檔

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="SliverlightOne.App"
             >
    <Application.Resources>
        <Style x:Key="keyBody" TargetType="Body">
            <Setter Property="Margin" Value="0, 10, 0, 0"/>
        </Style>
    </Application.Resources>
</Application>

*.xaml檔

<Grid x:Name="LayoutRoot" Background="White">
    <Body></Body>
    <Body Style="{StaticResource keyBody}"></Body>
</Grid>
</html>
第一種使用Style的方式,是直接用TargetType的隱喻。像是最初的CSS一樣,直接定義某標籤的Style之後呼叫使用預設Style直接套用。
另一種是指定Key,在CSS中,就是指定id或class的方式。被指定者才適用於該Style。

在Silverlight中,每一個元素都有屬於自己的resource(CSS的說法,就是「每個元素都可以定義該元素自己的Style」),當解析到這一個markup,Silverlight會先找該markup(就是有"{StaticResource ResourceName}"的時候)的resource,如果沒有找到相同名稱的就再往一層去找,一直找到Application的這一層。

所以,Application有全域Resource的感覺,而XAML的樹,各個分支都算是區域的resource。



最後,將資源的Style獨立成一個檔案,才是真正像CSS的功能。
先在VS上→方案管理員中按右鍵→Add→New Item→Silverlight Resource Dictionary
新增的Dictionary1.xaml檔,把元素貼過來。

Dictionary1.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="keyBody" TargetType="Body">
        <Setter Property="Margin" Value="0, 10, 0, 0"/>
    </Style>
</ResourceDictionary>

App.xaml檔

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="SliverlightOne.App"
             >
    <Application.Resources>

      <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="ElementBrushes.xaml" />
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>

    </Application.Resources>
</Application>
最後在使用該Resource的*.xaml檔無需修改。
只是這個引用外部資源的語法也太長了點。

Sliverlight//Bindling

沒有留言:
一開始,先來看看Binding without C#的做法,適合給前端的視覺設計做動態頁面時,有全權的決定權(因為,都用XAML)。
這個例子是一個Slider調整TextBlock的FontSize屬性。
拉動Slider,TextBlock的字型大小就會改變。 XML檔
<Slider x:Name="sliderFontSize" Minimum="9" Maximum="400" Value="16"/>
<TextBlock x:Name="lblSampleText" Text="Simple Text" 
           FontSize="{Binding ElementName=sliderFontSize, Path=Value}"/>
Binding時,ElementName指定XAML的物件,並且使用Path指定該物件的其中一個屬性。達到了不需要C#而達到了動態頁面的效果。
我們來看看,如何利用CS建立物件並且利用Blinding呼叫物件屬性顯示在XML上面的兩個例子。

Binding有分成三種模式。

(目前,都還沒加上C#,以純XAML的物件傳值在討論)
  • One-time: 
  • 將目標記憶體位址初始化此XML的屬性,並且取消Binding的關係。
  • One-Way: 
  • 此XML的屬性,像(C++的)指標指向某指定的記憶體位址,如果XML的屬性被覆寫,就失去了Binding的關係,如果覆寫記憶體位址,則會更新XML的屬性。
  • Two-Way: 
  • 此XML的屬性,像(C++的)參考,與某一個XML的物件互為同一個記憶體位址,可以更新(XML的物件)彼此。


後續是有加上C#的code時,Bindling的情況,我自己也不是很懂!哈哈。

第一個例子,介面的Button如何和程式碼的Button連結在一起,並且觸發Click的事件,並且執行設定好關聯的函式myButton_Click。

XML檔
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Canvas ...>
            <Button Name="xmlButton" Click="myButton_Click" Content="{Binding Content}" ... />
        </Canvas>
        
    </Grid>
CS檔
namespace SliverlightOne
{
    public partial class MainPage : UserControl
    {
        //...
        private int i;

        public MainPage()
        {
            InitializeComponent();

            Button csButton = new Button() { Content = "this is ..." };//obj editor
            xmlButton.DataContext = csButton; //xml obj = cs obj
            //...
        }

        private void myButton_Click(object sender, RoutedEventArgs e)
        {
            xmlButton.Content = ++i;
        }
        //...
    }
}
第二個例子,我們來看看介面的DataGrid和CS的List如何建立關聯性,並且利用Blinding呼叫物件屬性顯示在介面上。
XML檔
其中 Canvas.Left="10" AutoGenerateColumns="False" 不自動生成顯示表格,為了要自訂欄位標籤
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Canvas Grid.Column="1" ...>
            <sdk:DataGrid Name="dgData" Canvas.Left="10" AutoGenerateColumns="False" ...>
                <sdk:DataGrid.Columns>
                    <sdk:DataGridTextColumn Binding="{Binding Id}" Header="_Id"/>
                    <sdk:DataGridTextColumn Binding="{Binding Name}" Header="_Name"/>
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>

        </Canvas>
    </Grid>
</UserControl>
CS檔
namespace SliverlightOne
{
    public partial class MainPage : UserControl
    {
        public class abc  //define my Data class
        {
            private string cv_Id;

            public string Id
            {
                get { return cv_Id; }
                set { cv_Id = value; }
            }
        }

        public MainPage()
        {
            InitializeComponent();
            //...
            List<abc> tList = new List<abc>();
            tList.Add(new abc { Id = "a", Name = "aa" });
            tList.Add(new abc { Id = "B", Name = "BB" });
            dgData.ItemsSource = tList; //xml obj = cs obj
        }
    }
}