Skip to main content

Microsoft Silverlight

Unanswered Question Welcome, Learning Resources and Silverlight ToolkitRSS Feed

(1)

JustinAngel
JustinAngel

Contributor

Contributor

4415 points

596 Posts

Welcome, Learning Resources and Silverlight Toolkit

HI Folks,

Welcome to the Silverlight Controls Forum which encompasses the Silverlight framework controls, Silverlight SDK controls and the Silverlight Toolkit

Here are some resources that will help you get started:
   1.       Silverlight UI Controls, official tutorial by Jesse Liberty
  
2.       Silverlight 2 Controls Videos, on Silverlight.Net  
  
3.       Download the Silverlight Toolkit 
  
4.       Read the Silverlight Toolkit overview on the Silverlight Toolkit website

Before asking a question please look over our forum for existing questions and search the Silverlight Toolkit Issue Tracker.

When asking questions, please add a short explanation as to what you're trying to achieve, and a minimal and relevant code sample.  This forum is actively monitored by Silverlight Toolkit team members. 

Sincerely,
Microsoft Silverlight Toolkit Team

FAQ

1. Toolkit [top]

1.1 What is a Silverlight Toolkit and where can I download it? [top]

The Silverlight Toolkit is a collection of Silverlight controls, components and utilities made available outside the normal Silverlight release cycle. It adds new functionality for designers and developers, and provides the community an efficient way to help shape product development by contributing ideas and bug reports. It includes full source code unit tests, samples and documentation for 12 new controls covering charting, styling, layout, and user input.

You can download the Toolkit from:

http://www.codeplex.com/Silverlight

 

 

2. Built-in Controls: [top]

2.1 How to open a new window/tab when a HyperlinkButton is clicked? [top]

You have two options:

  • Simply set the TargetName property of the HyperlinkButton control to _blank. Below is the sample.

<HyperlinkButton NavigateUri="http://www.microsoft.com" Content="Click Me"  TargetName="_blank"></HyperlinkButton>

  • If you’re looking for an effect like what window.open function brings to us in JavaScript you can call this JavaScript function from managed code. Below is the sample:

1. Xaml:

<HyperlinkButton Content="Click Me"  Click="HyperlinkButton_Click"></HyperlinkButton>

2. Xaml.cs:

 

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)

{

HtmlPage.Window.Eval("window.open(\"http://www.microsoft.com\")");

}

Please refer to the following documentation about HtmlWindow.Eval method: http://msdn.microsoft.com/en-us/library/system.windows.browser.htmlwindow.eval(VS.95).aspx

2.2 How to remove the border of a TextBox control? [top]

Sometimes we need to change the style of a control and find it’s impossible to do that via the exposed property of that control. In this case we can overwrite the default template of this control to achieve the requirement. Here’s a sample that demonstrates how to remove the border of a TextBox control. By default, when you set the BorderThickness property to 0 you’ll still see the border if your mouse hovers on the TextBox.

  

<UserControl x:Class="FAQ_Built_in_Controls.Page"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Width="400" Height="300"

xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">

  <UserControl.Resources>

    <Style x:Key="TextBoxStyle1" TargetType="TextBox">

      <Setter Property="BorderThickness" Value="1"/>

      <Setter Property="Background" Value="#FFFFFFFF"/>

      <Setter Property="Foreground" Value="#FF000000"/>

      <Setter Property="Padding" Value="2"/>

      <Setter Property="BorderBrush">

        <Setter.Value>

          <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

            <GradientStop Color="#FFA3AEB9" Offset="0"/>

            <GradientStop Color="#FF8399A9" Offset="0.375"/>

            <GradientStop Color="#FF718597" Offset="0.375"/>

            <GradientStop Color="#FF617584" Offset="1"/>

          </LinearGradientBrush>

        </Setter.Value>

  </Setter>

  <Setter Property="Template">

    <Setter.Value>

      <ControlTemplate TargetType="TextBox">

        <Grid x:Name="RootElement">

              <vsm:VisualStateManager.VisualStateGroups>

                <vsm:VisualStateGroup x:Name="CommonStates">

                  <vsm:VisualState x:Name="Normal"/>

                  <vsm:VisualState x:Name="MouseOver">

                                  <Storyboard>

                                    <ColorAnimationUsingKeyFrames               

                 Storyboard.TargetName="MouseOverBorder"                  

                 Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">

                        <SplineColorKeyFrame KeyTime="0" Value="#FF99C1E2"/>

                      </ColorAnimationUsingKeyFrames>

                    </Storyboard>

                  </vsm:VisualState>

  

                  <vsm:VisualState x:Name="Disabled">

                    <Storyboard>

                      <DoubleAnimationUsingKeyFrames

                             Storyboard.TargetName="DisabledVisualElement"

                             Storyboard.TargetProperty="Opacity">

                        <SplineDoubleKeyFrame KeyTime="0" Value="1"/>

                      </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                  </vsm:VisualState>

                  <vsm:VisualState x:Name="ReadOnly">

                    <Storyboard>

                      <DoubleAnimationUsingKeyFrames

                            Storyboard.TargetName="ReadOnlyVisualElement"

                            Storyboard.TargetProperty="Opacity">

                        <SplineDoubleKeyFrame KeyTime="0" Value="1"/>

                      </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                  </vsm:VisualState>

                </vsm:VisualStateGroup>

                <vsm:VisualStateGroup x:Name="FocusStates">

                  <vsm:VisualState x:Name="Focused">

                    <Storyboard>

                      <DoubleAnimationUsingKeyFrames

                            Storyboard.TargetName="FocusVisualElement"

                            Storyboard.TargetProperty="Opacity">

                        <SplineDoubleKeyFrame KeyTime="0" Value="1"/>

                      </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                  </vsm:VisualState>

                  <vsm:VisualState x:Name="Unfocused">

                    <Storyboard>

                      <DoubleAnimationUsingKeyFrames

                            Storyboard.TargetName="FocusVisualElement"

                            Storyboard.TargetProperty="Opacity">

                        <SplineDoubleKeyFrame KeyTime="0" Value="0"/>

                      </DoubleAnimationUsingKeyFrames>

                    </Storyboard>

                  </vsm:VisualState>

                </vsm:VisualStateGroup>

              </vsm:VisualStateManager.VisualStateGroups>

  

              <Border x:Name="Border" Opacity="1"

                    Background="{TemplateBinding Background}"

                    BorderBrush="{TemplateBinding BorderBrush}"

                    BorderThickness="{TemplateBinding BorderThickness}"

                    CornerRadius="1">

                <Grid>

                  <Border x:Name="ReadOnlyVisualElement" Opacity="0"

                          Background="#72F7F7F7"/>

                  <Border x:Name="MouseOverBorder" BorderBrush="Transparent"

                          BorderThickness="0">

                    <ScrollViewer  x:Name="ContentElement" BorderThickness="0"

                                  IsTabStop="False"

                                  Padding="{TemplateBinding Padding}"/>

                  </Border>

                </Grid>

              </Border>

              <Border x:Name="DisabledVisualElement" IsHitTestVisible="False"

                      Opacity="0" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7"

                      BorderThickness="{TemplateBinding BorderThickness}"/>

              <Border Margin="1" x:Name="FocusVisualElement" IsHitTestVisible="False"

                      Opacity="0" BorderBrush="#FF6DBDD1"

                      BorderThickness="{TemplateBinding BorderThickness}"/>

            </Grid>

          </ControlTemplate>

        </Setter.Value>

      </Setter>

    </Style>

  </UserControl.Resources>

  <Grid x:Name="LayoutRoot" Background="White" >

    <StackPanel>

      <TextBlock Text="There's a TextBox below"></TextBlock>    

      <TextBox Background="Red" Style="{StaticResource TextBoxStyle1}"

               BorderThickness="0"/>

    </StackPanel>

  </Grid>

</UserControl>

 

You can find the default templates of the built-in controls from the following documentation:

http://msdn.microsoft.com/en-us/library/cc278075(VS.95).aspx

If you don’t want to type the Xaml manually, you can use Expression Blend to help  modify the templates. Please refer to the following video for more information.

           http://expression.microsoft.com/en-us/dd334546.aspx      

In the following FAQs Xaml code is shown directly for you to test in Visual Studio but it's always easier to edit Xaml in Blend. You can go to the following web sites to learn more about Expression Blend:

              http://www.microsoft.com/Expression/products/Overview.aspx?key=blend

              http://social.expression.microsoft.com/forums/en-us/blend/threads/

 

2.3 Why the MouseLeftButtonDown event of the Button control never fires? [top]

It’s an expected behavior in Silverlight 2 RTW. If you really want an entry for you to do something on the MouseLeftButtonDown event or the MouseLeftButtonUp event you can write your own control deriving from the Button class. Below is the sample code:

MyButton.cs:

   

   public class MyButton : System.Windows.Controls.Button

    {

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)

        {

            base.OnMouseLeftButtonDown(e);

            e.Handled = false;

        }

 

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)

        {

            base.OnMouseLeftButtonUp(e);

            e.Handled = false;

        }

}

Test code:

Xaml:

   

<StackPanel>

<c:MyButton Width="200" Height="50" Content="Click Me"

MouseLeftButtonDown="MyButton_MouseLeftButtonDown"

MouseLeftButtonUp="MyButton_MouseLeftButtonUp"

Click="MyButton_Click"></c:MyButton>

<TextBlock x:Name="TextBlock1"></TextBlock>

<TextBlock x:Name="TextBlock2"></TextBlock>

</StackPanel>

 

Xaml.cs:

   

private void MyButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

this.TextBlock2.Text = String.Empty;

this.TextBlock1.Text = "Down";

}

 

private void MyButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)

{

this.TextBlock1.Text = "Up"

}

 

private void MyButton_Click(object sender, RoutedEventArgs e)

{

this.TextBlock2.Text = "Clicked!";

}

Related post:

http://silverlight.net/forums/p/22148/104277.aspx#104277

2.4 How do I trigger the Click event of a Button control when the enter key is pressed? [top]

You can hook the KeyDown event of the Page class and in the KeyDown event handler execute the same code in the Button’s click event handler. However, in some cases the target button may change and it’s difficult to get the button’s reference from the Page’s view (for instance, when the button is in the DataTemplate). In this case we can write a control deriving from the button to expose a method to force triggering click event. Below is the code that demonstrates how to do this. To test, please select a TextBox of a certain row and press enter key. Then the Click event of the button on the same row will fire.

Xaml:

              

<StackPanel>

<TextBlock x:Name="TextBlock1"></TextBlock>

<ListBox x:Name="ListBox1">

<ListBox.ItemTemplate>

<DataTemplate>

<StackPanel>

<TextBox KeyDown="TextBox_KeyDown"></TextBox>

<c:MyButton Tag="{Binding}"  x:Name="Button1"

Click="Button_Click"

Content="Click Me"></c:MyButton>

</StackPanel>

</DataTemplate>

</ListBox.ItemTemplate>

</ListBox>

</StackPanel>

 

Xaml.cs:

    

public partial class Page : UserControl

{

public Page()

{

InitializeComponent();

this.Loaded += new RoutedEventHandler(Page_Loaded);

}

 

void Page_Loaded(object sender, RoutedEventArgs e)

{

this.ListBox1.ItemsSource = "0123456789";

}

 

private void Button_Click(object sender, RoutedEventArgs e)

{

Button b = (Button)sender;

this.TextBlock1.Text = "Button clicked: " + b.Tag;

}

private void TextBox_KeyDown(object sender, KeyEventArgs e)

{

if (e.Key == Key.Enter)

{

MyButton b = ((TextBox)sender).FindName("Button1") as MyButton;

if (b != null)

{

b.ForceClick();

}

}

}

}

public class MyButton : Button

{

public void ForceClick() { this.OnClick(); }

}

2.5 How do I change the background color of the cell in the Calendar control for a particular date? [top]

While the built-in Calendar control has no DayRender event it’s still possible to do this. One option is to store all the references of the rectangles that renders the date cells and change the background color of these rectangles when the display date get changed. We can get the date attached to the date cell via DataContext property. Below the code that demonstrates how to do this.

Xaml:

              

<UserControl xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  x:Class="FAQ_Built_in_Controls.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:C="clr-namespace:FAQ_Built_in_Controls"

    xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls"

    Width="400" Height="300" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">

    <UserControl.Resources>

        <Style x:Key="CalendarDayButtonStyle1" TargetType="primitives:CalendarDayButton">

            <!-- Date button properties -->

            <Setter Property="Background" Value="#FFBADDE9"/>

            <Setter Property="MinWidth" Value="5"/>

            <Setter Property="MinHeight" Value="5"/>

            <Setter Property="FontSize" Value="10"/>

            <Setter Property="HorizontalContentAlignment" Value="Center"/>

            <Setter Property="VerticalContentAlignment" Value="Center"/>

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="primitives:CalendarDayButton">

                        <Grid x:Name="Root" >

                            <vsm:VisualStateManager.VisualStateGroups>

                                <vsm:VisualStateGroup x:Name="CommonStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0:0:0.1" />

                                    </vsm:VisualStateGroup.Transitions>

                                    <vsm:VisualState x:Name="Normal" />

                                    <vsm:VisualState x:Name="MouseOver">

                                        <Storyboard>

                                            <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />

                                        </Storyboard>

                                    </vsm:VisualState>

 

              

                                    <vsm:VisualState x:Name="Pressed">

                                        <Storyboard>

                                            <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />

                                        </Storyboard>

                                    </vsm:VisualState>

                                    <vsm:VisualState x:Name="Disabled">

                                        <Storyboard>

                                            <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To="0" Duration="0" />

                                            <DoubleAnimation Storyboard.TargetName="NormalText" Storyboard.TargetProperty="Opacity" To=".35" Duration="0" />

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

                                <vsm:VisualStateGroup x:Name="SelectionStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0" />

                                    </vsm:VisualStateGroup.Transitions>

                                    <vsm:VisualState x:Name="Unselected" />

                                    <vsm:VisualState x:Name="Selected">

                                        <Storyboard>

                                            <DoubleAnimation Storyboard.TargetName="SelectedBackground" Storyboard.TargetProperty="Opacity" To=".75" Duration="0" />

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

                                <vsm:VisualStateGroup x:Name="CalendarButtonFocusStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0" />

                                    </vsm:VisualStateGroup.Transitions>

 

            

                                    <vsm:VisualState x:Name="CalendarButtonFocused">

                                        <Storyboard>

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DayButtonFocusVisual" Storyboard.TargetProperty="Visibility" Duration="0">

                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>

                                            </ObjectAnimationUsingKeyFrames>

                                        </Storyboard>

                                    </vsm:VisualState>

                                    <vsm:VisualState x:Name="CalendarButtonUnfocused">

                                        <Storyboard>

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DayButtonFocusVisual" Storyboard.TargetProperty="Visibility" Duration="0">

                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>

                                            </ObjectAnimationUsingKeyFrames>

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

                                <vsm:VisualStateGroup x:Name="ActiveStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0" />

                                    </vsm:VisualStateGroup.Transitions>

                                    <vsm:VisualState x:Name="Active" />

                                    <vsm:VisualState x:Name="Inactive">

                                        <Storyboard>

                                            <ColorAnimation Duration="0" Storyboard.TargetName="selectedText" Storyboard.TargetProperty="Color" To="#FF777777"></ColorAnimation>

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

   

                                <vsm:VisualStateGroup x:Name="DayStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0" />

                                    </vsm:VisualStateGroup.Transitions>

                                    <vsm:VisualState x:Name="RegularDay" />

                                    <vsm:VisualState x:Name="Today">

                                        <Storyboard>

                                            <DoubleAnimation Storyboard.TargetName="TodayBackground" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />

                                            <ColorAnimation Duration="0" Storyboard.TargetName="selectedText" Storyboard.TargetProperty="Color" To="#FFFFFFFF"></ColorAnimation>

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

                                <vsm:VisualStateGroup x:Name="BlackoutDayStates">

                                    <vsm:VisualStateGroup.Transitions>

                                        <vsm:VisualTransition GeneratedDuration="0" />

                                    </vsm:VisualStateGroup.Transitions>

                                    <vsm:VisualState x:Name="NormalDay" />

                                    <vsm:VisualState x:Name="BlackoutDay">

                                        <Storyboard>

                                            <DoubleAnimation Duration="0" Storyboard.TargetName="Blackout" Storyboard.TargetProperty="Opacity" To=".2"/>

                                        </Storyboard>

                                    </vsm:VisualState>

                                </vsm:VisualStateGroup>

                            </vsm:VisualStateManager.VisualStateGroups>

                            <Rectangle x:Name="TodayBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="#FFAAAAAA"/>

                            <Rectangle x:Name="SelectedBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}"/>

                            <Rectangle x:Name="Background" RadiusX="1" RadiusY="1"  Loaded="Background_Loaded"/>

 

   

                            <ContentControl

                                x:Name="NormalText"

                                IsTabStop="False"

                                Content="{TemplateBinding Content}"

                                ContentTemplate="{TemplateBinding ContentTemplate}"

                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"

                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"

                                FontSize="{TemplateBinding FontSize}"

                                Margin="5,1,5,1">

                                <ContentControl.Foreground>

                                    <SolidColorBrush x:Name="selectedText" Color="#FF333333"/>

                                </ContentControl.Foreground>

                            </ContentControl>

                            <Path x:Name="Blackout" Opacity="0" Margin="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5" Fill="#FF000000" Stretch="Fill" Data="M8.1772461,11.029181 L10.433105,11.029181 L11.700684,12.801641 L12.973633,11.029181 L15.191895,11.029181 L12.844727,13.999395 L15.21875,17.060919 L12.962891,17.060919 L11.673828,15.256231 L10.352539,17.060919 L8.1396484,17.060919 L10.519043,14.042364 z"/>

                            <Rectangle  x:Name="DayButtonFocusVisual" Visibility="Collapsed" IsHitTestVisible="false" RadiusX="1" RadiusY="1" Stroke="#FF6DBDD1"/>

                        </Grid>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

     

    </UserControl.Resources>

        <Grid x:Name="LayoutRoot" Background="White" >

 

                    <basics:Calendar  DisplayDateChanged="Calendar1_DisplayDateChanged" x:Name="Calendar1"  Width="300" Height="300" CalendarDayButtonStyle="{StaticResource CalendarDayButtonStyle1}" RenderTransformOrigin="0.5,0.5">

                    </basics:Calendar>

           

    </Grid>

</UserControl>

 

Xaml.cs:

              

namespace FAQ_Built_in_Controls

{

    public partial class Page : UserControl

    {

        List<Rectangle> list = new List<Rectangle>();

        public Page()

        {

            InitializeComponent();

        }

     

        static Random rdm = new Random();

        private void Background_Loaded(object sender, RoutedEventArgs e)

        {

            Rectangle r = (Rectangle)sender;

            list.Add(r);

            ChangeDateCellColor(r);

        }

        private void Calendar1_DisplayDateChanged(object sender, CalendarDateChangedEventArgs e)

        {

            foreach (Rectangle r in list) {

                ChangeDateCellColor(r);

            }

        }

        private void ChangeDateCellColor(Rectangle datecell)

        {

            if (datecell != null)

            {

                DateTime dt = (DateTime)datecell.DataContext;

                if (dt.Day % 3 == 0)

                    datecell.Fill = new SolidColorBrush(Colors.Red);

                else

                {

                    datecell.Fill = new SolidColorBrush(Colors.White);

                }

            }

        }

    }

}

 

2.6 How do I get the reference of a control in a DataGrid? [top]

You can try DataGrid.Columns[index].GetCellContent() to do so. Below is a sample:

Xaml:

          

<StackPanel>

<Button Width="200" Height="50" Content="Click Me" Click="Button_Click"></Button>

<data:DataGrid x:Name="DataGrid1">

<data:DataGrid.Columns>

<data:DataGridTemplateColumn>

<data:DataGridTemplateColumn.CellTemplate>

<DataTemplate>

<StackPanel>

<TextBlock></TextBlock>

</StackPanel>

</DataTemplate>

</data:DataGridTemplateColumn.CellTemplate>

</data:DataGridTemplateColumn>

</data:DataGrid.Columns>

</data:DataGrid>

</StackPanel>

Xaml.cs:

              

public partial class Page : UserControl

{

public Page()

{

InitializeComponent();

this.Loaded += new RoutedEventHandler(Page_Loaded);

}

void Page_Loaded(object sender, RoutedEventArgs e)

{

this.DataGrid1.ItemsSource = "Hello World!";

}

private void Button_Click(object sender, RoutedEventArgs e)

{

StackPanel sp = (StackPanel)this.DataGrid1.Columns[0].GetCellContent('e');

TextBlock tb = (TextBlock)sp.Children[0];

tb.Text = DateTime.Now.ToString();

}

}

2.7 How do I sort the DataGrid when custom header is used? [top]

The way to add a custom header for DataGrid is changed in Silverlight 2 RTW. See the following links for more details:

http://silverlight.net/forums/p/30592/99042.aspx#99042

To sort the DataGrid, we can simply sort the datasource and then rebind the DataGrid. Below is a sample.

Xaml:

              

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  x:Class="FAQ_Built_in_Controls.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:c="clr-namespace:FAQ_Built_in_Controls"

    xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"

 

xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls"

    Width="400" Height="500"

    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">

        <Grid x:Name="LayoutRoot" Background="White" >

                <data:DataGrid AutoGenerateColumns="False" CanUserResizeColumns="False"  x:Name="DataGrid1" Width="202">

                    <data:DataGrid.Columns>

                    <data:DataGridTemplateColumn>

                        <data:DataGridTemplateColumn.HeaderStyle>

                                <Style TargetType="dataprimitives:DataGridColumnHeader">

                                    <Setter Property="Template">

                                        <Setter.Value>

                                            <ControlTemplate>

                                                <Button Width="200" Height="50" Content="Sort" Click="Button_Click" />

                                            </ControlTemplate>

                                        </Setter.Value>

                                    </Setter>

                                </Style>

 

              

                       </data:DataGridTemplateColumn.HeaderStyle>

                        <data:DataGridTemplateColumn.CellTemplate>

                            <DataTemplate>

                                <StackPanel>

                                    <TextBlock Text="{Binding age}"></TextBlock>

                                </StackPanel>

                            </DataTemplate>

                        </data:DataGridTemplateColumn.CellTemplate>

                    </data:DataGridTemplateColumn>

                </data:DataGrid.Columns>

            </data:DataGrid>         

    </Grid>

</UserControl>

Xaml.cs:

              

namespace FAQ_Built_in_Controls

{

    public partial class Page : UserControl

    {

        bool flag = false;

        List<Customer> list = new List<Customer>();//our data source

        public Page()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Page_Loaded);

        }

        void Page_Loaded(object sender, RoutedEventArgs e)

        {

            for (int i = 0; i < 10; i++)

            {

                Customer c = new Customer { age = i };

                list.Add(c);

            }

            this.DataGrid1.ItemsSource = list;

        }

 

                                          

        public void Button_Click(object sender, RoutedEventArgs e)

        {

            if (flag)

            {

               list= list.OrderBy(i => i.age).ToList();

            }

            else

            {

               list= list.OrderByDescending(i => i.age).ToList();

            }

            flag = !flag;

            this.DataGrid1.ItemsSource = list;

        }

    }

    public class Customer : INotifyPropertyChanged

    {

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private int _age;

        public int age

        {

            get { return _age; }

            set

            {

                _age = value;

                if (PropertyChanged != null)

                {

                    PropertyChanged(this, new PropertyChangedEventArgs("age"));

                }

            }

        }

        #endregion

    }

}

2.8 Where is the Sorting event of the DataGrid?  [top]

Unfortunately the function is not currently supported. A possible workaround is to use custom headers to sort the DataGrid, as mentioned in #1.7.

 

2.9 How do I customize auto-generated columns in the DataGrid control? [top]

You can handle the AutoGeneratingColumn event to modify, replace, or cancel a column that is being generated. The AutoGeneratingColumn event occurs one time for each public, non-static property in the bound data type when the ItemsSource property is changed and the AutoGenerateColumns property is true.

For more details please check out

http://msdn.microsoft.com/en-us/library/cc903950(VS.95).aspx

2.10 How do I create clickable Deep Zoom?  [top]

Firstly, you need to expose images as collection in the Deep Zoom Composer. Then you will get  MultiScaleImage via MultiScaleImage.SubImages collection. It represents a single image. Below is the sample:

Xaml:

              

<MultiScaleImage MouseLeftButtonUp="MultiScaleImage1_MouseLeftButtonUp"  x:Name="MultiScaleImage1" Source="dzc_output.xml" Width="800" Height="600"></MultiScaleImage>

 

Xaml.cs:

              

public partial class Page : UserControl

{

List<int> subimageindexlist=new List<int>();

public Page()

{

InitializeComponent();

}

List<int> SubImageHitTest(Point p)

{

List<int> result = new List<int>();

for (int i = 0; i < this.MultiScaleImage1.SubImages.Count; i++)

                 {

Rect subImageRect = GetSubImageRect(i);

if (subImageRect.Contains(p))

{

result.Add(i);

}

}

return result;

}

              

Rect GetSubImageRect(int indexSubImage)

{

if (indexSubImage < 0 || indexSubImage >= this.MultiScaleImage1.SubImages.Count)

return Rect.Empty;

MultiScaleSubImage subImage = this.MultiScaleImage1.SubImages[indexSubImage];

double scaleBy = 1 / subImage.ViewportWidth;

return new Rect(-subImage.ViewportOrigin.X * scaleBy, -subImage.ViewportOrigin.Y * scaleBy, 1 * scaleBy, (1 / subImage.AspectRatio) * scaleBy);

}

private void MultiScaleImage1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)

{

MultiScaleImage msi = (MultiScaleImage)sender;

//reset opacity

            if (subimageindexlist.Count > 0)

            {

                           for (int i = 0; i < subimageindexlist.Count; i++)

{

msi.SubImages[subimageindexlist[ i]].Opacity = 1;

}

            }

            subimageindexlist.Clear();

            //set opacity for the selected one

            Point p=msi.ElementToLogicalPoint(e.GetPosition(msi));

            subimageindexlist =SubImageHitTest(p);

            for (int i = 0; i < subimageindexlist.Count; i++)

            {

                msi.SubImages[subimageindexlistIdea].Opacity =0.5;

            }

}

}

Reference:

http://projectsilverlight.blogspot.com/

 

2.11 How do I work with VSM in code behind? [top]

While sometimes you may want to modify visual states in code behind, this is generally not recommended because it will break the designer and developer workflow. However, it is still very useful.

Imagine you have the following Button ControlTemplate:

   

<ControlTemplate TargetType="Button">

<Grid Loaded="Grid_Loaded">

<vsm:VisualStateManager.VisualStateGroups>

<vsm:VisualStateGroup x:Name="CommonStates">

<vsm:VisualState x:Name="Normal">

<Storyboard>

<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">

<SplineColorKeyFrame KeyTime="00:00:00" Value="#FF20FF00"/>

</ColorAnimationUsingKeyFrames>

</Storyboard>

</vsm:VisualState>

<vsm:VisualState x:Name="MouseOver">

<Storyboard>

<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">

<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFFF8484"/>

</ColorAnimationUsingKeyFrames>

</Storyboard>

</vsm:VisualState>

<vsm:VisualState x:Name="Pressed">

<Storyboard/>

</vsm:VisualState>

<vsm:VisualState x:Name="Disabled">

                                     <Storyboard/>

</vsm:VisualState>

</vsm:VisualStateGroup>

<vsm:VisualStateGroup x:Name="FocusStates">

<vsm:VisualState x:Name="Focused">

<Storyboard/>

</vsm:VisualState>

<vsm:VisualState x:Name="Unfocused"/>

</vsm:VisualStateGroup>

   

</vsm:VisualStateManager.VisualStateGroups>

<Border x:Name="Background" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" Background="#FF000000"/>

<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>

         </Grid>

</ControlTemplate>

 

What can you do if you want to modify the Storyboard in MouseOver state based on a user’s input? For example, you can use two RadioButtons to allow the user to choose what color they like.

   

<RadioButton Height="21" HorizontalAlignment="Left" Margin="58,30.5,0,0" x:Name="RadioBlue" VerticalAlignment="Top" Width="106" Content="Blue" GroupName="group1" Checked="RadioBlue_Checked"/>

<RadioButton Height="18" HorizontalAlignment="Right" Margin="0,32,98,0" x:Name="RadioRed" VerticalAlignment="Top" Width="101" RenderTransformOrigin="0.5,0.5" Content="Red" GroupName="group1" Checked="RadioRed_Checked">

 

In this situation, you can work with the VSM in code behind. First you have to get a reference to the root Grid in the ControlTemplate. You can handle the Loaded event and reference it via the sender property:

   

private Grid grid;

private void Grid_Loaded(object sender, RoutedEventArgs e)

{

this.grid = (Grid)sender;

}

Now you can use a LINQ query to find the MouseOver state, and modify its Storyboard:

   

private void RadioBlue_Checked(object sender, RoutedEventArgs e)

{

if (this.grid != null)

{

Storyboard sb = (from VisualState state in

         (from VisualStateGroup g in VisualStateManager.GetVisualStateGroups(this.grid)

                                     where g.Name == "CommonStates"

                                     select g).FirstOrDefault().States

                                     where state.Name == "MouseOver"

                                     select state).FirstOrDefault().Storyboard;

                   ((ColorAnimationUsingKeyFrames)sb.Children[0]).KeyFrames[0].Value = Color.FromArgb(0xff, 0x00, 0x97, 0xff);

         }

}

 

 

3. Custom Controls: [top]

3.1 Why doesn’t the OnApplyTemplate() method of my custom control fire? [top]

  • Make sure the built action of the generic.xaml is set as Resource.
  • Make sure the generic.xaml is put in the Themes folder of the project.
  • Make sure you have added following code in the constructor of your custom control class:

   

DefaultStyleKey = typeof(YourCustomControlClass);

3.2 How do I add collection DependencyProperty for my custom control? [top]

The method for doing this is mentioned in the following post. We need to make some modifications due to breaking changes in a newer version.

http://silverlight.net/forums/t/12664.aspx

The updated code:

Generic.xaml:

              

<ResourceDictionary

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:src="clr-namespace:SilverlightApplication1;assembly=SilverlightApplication1" >

     <Style TargetType="src:Toolbar">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="src:Toolbar">

                    <Canvas x:Name="ItemCanvas"

                            Width="{TemplateBinding Width}"

Height="{TemplateBinding Height}" >

                    </Canvas>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

    <Style TargetType="src:ToolbarItem">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="src:ToolbarItem">                  

                    <ContentControl

                      Content="{TemplateBinding Content}"

                      ContentTemplate="{TemplateBinding ContentTemplate}"

                      FontFamily="{TemplateBinding FontFamily}"

                      FontSize="{TemplateBinding FontSize}"

                      FontStretch="{TemplateBinding FontStretch}"

                      FontStyle="{TemplateBinding FontStyle}"

                      FontWeight="{TemplateBinding FontWeight}"

                      Foreground="{TemplateBinding Foreground}"

                      HorizontalAlignment="Left"

                      HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"

                      Padding="{TemplateBinding Padding}"

                      VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

</ResourceDictionary>

Toolbar.cs:

              

using System;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using System.Collections.ObjectModel;

 

namespace SilverlightApplication1

{

    public class Toolbar : Control

    {

        public Toolbar()

        {

            Items = new ToolbarItemCollection();

            DefaultStyleKey = typeof(Toolbar);

        }

 

        public ToolbarItemCollection Items

        {

            get { return (ToolbarItemCollection)GetValue(ItemsProperty); }

            set { SetValue(ItemsProperty, value); }

        }

        public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ToolbarItemCollection), typeof(Toolbar), null);

 

              

        public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

            Canvas ItemCanvas = (Canvas)GetTemplateChild("ItemCanvas");

            double x = 0;

            foreach (ToolbarItem item in Items)

            {

                item.SetValue(Canvas.LeftProperty, x);

                FrameworkElement content = item.Content as FrameworkElement;

                x += content.Width + content.Margin.Right;

                ItemCanvas.Children.Add(item);

            }

        }

    }

 

    public class ToolbarItem : ContentControl

    {

    }

 

    public class ToolbarItemCollection : ObservableCollection<ToolbarItem>

    {

    }

}

 

Page.xaml:

              

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

             x:Class="SilverlightApplication1.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"

    xmlns:tb="clr-namespace:SilverlightApplication1;assembly=SilverlightApplication1"

    Width="1400" Height="1300" >

        

    <Grid x:Name="LayoutRoot" >

        <StackPanel>

            <tb:Toolbar>

                <tb:Toolbar.Items>

                    <tb:ToolbarItem>

                        <Rectangle Width="20" Height="20" Fill="Red" Margin="2 2 2 2"/>

                    </tb:ToolbarItem>

                    <tb:ToolbarItem>

                        <Rectangle Width="30" Height="20" Fill="Green" Margin="2 2 2 2"/>

                    </tb:ToolbarItem>

                    <tb:ToolbarItem>

                        <Rectangle Width="40" Height="20" Fill="Blue" Margin="2 2 2 2"/>

                    </tb:ToolbarItem>

                </tb:Toolbar.Items>

            </tb:Toolbar>

        </StackPanel>

    </Grid>

</UserControl>

 

 

4. UserControl:  [top]

4.1 How do I inherit a UserControl? [top]

You can try following steps to do so:

     1. Create a new Silverlight project named InheritUserControl.

2. Create a new Silverlight UserControl in the project. Name it as BaseControl.xaml.

3. In BaseControl.xaml, add a TextBlock in the Grid like below:

   

<Grid x:Name="LayoutRoot" Background="White">

<TextBlock Text="Base Control" x:Name="TextBlock1"></TextBlock>

</Grid>

 

4.   Create a new Silverlight UserControl in the project. Name it as DerivedControl.xaml.

5.    Add following code in DerivedControl.xaml.

   

<c:BaseControl x:Class="InheritUserControl.DerivedControl"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:c="clr-namespace:InheritUserControl"

    Width="400" Height="300">

    <c:BaseControl.Resources>

        <LinearGradientBrush x:Key="MyBrush1" StartPoint="0,0" EndPoint="1,1">

            <GradientStop Color="White"></GradientStop>

            <GradientStop Color="Blue" Offset="0.5"></GradientStop>

            <GradientStop Color="Black" Offset="1"></GradientStop>

        </LinearGradientBrush>

    </c:BaseControl.Resources>

</c:BaseControl>

 

6.   Add following code in DerivedControl.xaml.cs.

   

public partial class DerivedControl : BaseControl

    {

        public DerivedControl()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(DerivedControl_Loaded);

        }

 

        void DerivedControl_Loaded(object sender, RoutedEventArgs e)

        {

            this.TextBlock1.FontSize = 30;

            this.TextBlock1.Text = "Derived Control";

            this.TextBlock1.Foreground = (Brush)this.Resources["MyBrush1"];

        }

    }

 

Related post:

http://silverlight.net/forums/t/12448.aspx

 

4.2 How do I expose an event from a UserControl? [top]

Below is the sample:

UserControl.xaml.cs:

            

public partial class MyUserControl : UserControl

    {

        public delegate void MyEventHandler(object sender, MyEventArgs e);

        public event MyEventHandler Button1Click;

        public event MyEventHandler Button2Click;

 

        public MyUserControl()

        {

            InitializeComponent();

        }

 

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            Button1Click(sender, new MyEventArgs() { MyProperty = DateTime.Now });

        }

 

        private void Button_Click_1(object sender, RoutedEventArgs e)

        {

            Button2Click(sender, new MyEventArgs() { MyProperty = DateTime.Now });

        }

    }

    public class MyEventArgs : EventArgs

{

        public DateTime MyProperty { get; set; }

}


UserControl.xaml:

             

<Button Content="Button1" Width="200" Height="50" Click="Button_Click">

</Button>

<Button Content="Button2" Width="200" Height="50" Click="Button_Click_1">

</Button>

 

Page.xaml:

               

<c:MyUserControl Button1Click="UserControlButton1_Click" Button2Click="UserControlButton2_Click"></c:MyUserControl>

 

 

Page.xaml.cs:

                 

private void UserControlButton1_Click(object sender, MyEventArgs e)

{

this.TextBlock1.Text = ((Button)sender).Content.ToString() + " at: " + e.MyProperty.ToString();

}

 

private void UserControlButton2_Click(object sender, MyEventArgs e)

{

this.TextBlock1.Text = ((Button)sender).Content.ToString() + " at: " + e.MyProperty.ToString();

}

 

 

--
Justin Angel,
Blog @ http://silverlight.net/blogs/JustinAngel
Twitter @ http://twitter.com/JustinAngel
  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities