Archive

Archive for the ‘Sivlerlight 3’ Category

ListBox and scrolling

October 8, 2009 lee Leave a comment

When the listbox is bound to some data and when the data changes we may want to make the first item in the list visible.  That is not the default behaviour and ScrollIntoView(Item[0]) wont work. here is a way to reset the scrollposition

In the sample, I had the listbox’s  are bound to 200 items and when the button is clicked I set the items to 20. the listbox on the left shows the default behaviour , the listbox on the right  has the ScrollViewer position changed to show the first item  listbox scrolling
update: Looks like this method still has issues when the number of items changes from a very low number to  high number where the scrollbar appears and disappears as pointed out in this post. May be a bug?

update 2: Mog Liang (Microsoft Online Community Support) says “This is an known issue caused by ListBox virtualization. Currently, an workaround is replace VirtualizingStackPanel with StackPanel, however, this will drop the listbox performance.”

Here is the XAML and codebehind used in the sample

<Grid x:Name=”LayoutRoot” Margin=”5″>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            </Grid.ColumnDefinitions>
      <Button Content=”set to 20 items” Height=”28″ Width=”100″  HorizontalAlignment=”Right” Click=”Button_Click”/>
            <ListBox Grid.Column=”1″  Height=”200″ x:Name=”list1″ ItemsSource=”{Binding MyList}”/>
        <ListBox Grid.Column=”2″  Height=”200″ x:Name=”list2″ ItemsSource=”{Binding MyList}”/>
    </Grid>

 

public partial class MainPage : UserControl, INotifyPropertyChanged
    {
        public IEnumerable<string> MyList { get; set; }
        public MainPage()
        {
            InitializeComponent();
            MyList = Enumerable.Range(0, 200).Select(i => “Item..” + i.ToString()).ToList();
            this.DataContext = this;
           
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyList = Enumerable.Range(0, 20).Select(i => “Item..” + i.ToString()).ToList();
            NotifyPropertyChanged(“MyList”);
            ScrollViewer sv = GetChild<ScrollViewer>(list2);
            sv.ScrollToVerticalOffset(0);
        }

        public static T GetChild<T>(DependencyObject obj) where T : DependencyObject
        {
            DependencyObject child = null; for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child.GetType() == typeof(T))
                {
                    break;
                }
                else if (child != null)
                {
                    child = GetChild<T>(child);
                    if (child != null && child.GetType() == typeof(T))
                    {
                        break;
                    }
                }
            }
            return child as T;
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        } 

       
        #endregion
    }

Categories: Sivlerlight 3

Telerik Silverlight RadGridView Issues

September 24, 2009 lee 3 comments

I am new to Silverlight RadGridView control from (Q2 2009). I was trying to use a nested RadGridView in the RowDetailsTemplate like below.

Update: With the help of Vlad from Telerik, learned that there is a Service pack released which fixed issues 2 and 3, but scrolling seems to be still slow when compared to the regular DataGrid doing the samething and you see lot of flickering

I am having multiple issues.

<grid:RadGridView   x:Name=”RadGridView1″ ShowGroupPanel=”False”   IsReadOnly=”True”
                          RowIndicatorVisibility=”Collapsed”
                          AutoGenerateColumns=”False”  ColumnsWidthMode=”Fill”
                          RowDetailsVisibilityMode=”Visible”
                           CanUserFreezeColumns=”False” >
            <grid:RadGridView.Columns>
                …
            </grid:RadGridView.Columns>

            <grid:RadGridView.RowDetailsTemplate>
                <DataTemplate>
                    <Grid>
                        <grid:RadGridView  ShowColumnHeaders=”False” ShowGroupPanel=”False”
                                      ItemsSource=”{Binding ChildItems}”    IsReadOnly=”True” 
                                       Visibility=”Visible”
                          AutoGenerateColumns=”False”  ColumnsWidthMode=”Fill”
                          RowDetailsVisibilityMode=”Collapsed”
                           CanUserFreezeColumns=”False” >
                            <grid:RadGridView.Columns>
                                …
                            </grid:RadGridView.Columns>
                        </grid:RadGridView>
                    </Grid>
                </DataTemplate>
            </grid:RadGridView.RowDetailsTemplate>
        </grid:RadGridView>

1. With 10  rows of data. It is just not usable as scrolling takes long time. that is just for starters

2. I dont want to display any RowIndicator for the inner RadGridView. The property  “RowIndicatorVisibility” works correctly when set to “Collapsed” on the outer RadGridView when you add this property to the Inner RadGridView. you dont see any data in the Inner RadGridView

3. When the filter is applied, the inner RadGridView will not display any data

Tried to flatten the hierarchy but the filter functionality would be lost as I dont want to filter on the values of the InnerCollection and I could not find a way to tell dont include some values in the filter popup

If any one has any Ideas or workaround, please let me know

BTW,  the same scenario when using the DataGrid that comes with Silverlight, it seemed to work just fine, except for the ability to filter (out of the box)

Extended AutoCompleteBox sample updated to Silverlight 3

September 1, 2009 lee Leave a comment

A while back I had a sample that extends AutoCompleteBox which worked in Silverlight 2. Here is the sample upgraded to Silverlight 3. I did not add/remove anything functional. just fixed the errors that are caused by the changes in base class(AutoCompleteBox)

you can try a sample here and download the code here

Categories: Sivlerlight 3 Tags:

DataBinding in Nested Controls

August 27, 2009 lee 6 comments

Databinding can get tricky in a hurry depending on the layout we have and the model we are binding to. Dan Wahlin suggests a way in this post

Here is another way without any code or additional classes.

DataContext is setup to be a instance of data, which has list of customers(having name and city as properties) and an array of strings for cities. we would like to display customers in datagrid and display list of Cities in ComboBox and select the appropriate city for the customer

namespace SilverlightApplication2
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            this.DataContext = new Data();            
        }
    }
    public class Data
    {
        public List<Customer> Customers { get; set; }
        public string[] Cities { get; set; }
        public Data()
        {
            Customers = new List<Customer>();
            for (int i = 0; i < 10; i++)
                Customers.Add(new Customer { Name=”Customer..” + i.ToString(), City=”City..”+i.ToString() });

            Cities = new string[10];
            for (int i = 0; i < 10; i++)
                Cities[i] = “City..” + i.ToString();

        }
    }

    public class Customer
    {
        public string Name { get; set; }
        public string City { get; set; }
    }
}

the UI is set up like this. just a DataGrid with DataGridTextColumn for Name of the customer and ComboxBox for cities in a  DataGridTemplateColumn

Added a ContentControl( could be any control) to Resources which will have the same datacontext as the Root (Page/UserControl)

The ComboBox’s ItemsSource is set as shows in Bold, setting the source to the Resource and the path to its DataContext (in this case it will point to object of type “Data”) which has a property Cities. SelectedItem of the ComboBox is set to City of the customer

<UserControl xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”  x:Class=”SilverlightApplication2.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=”640″ d:DesignHeight=”480″>
    <UserControl.Resources>
        <ContentControl x:Key=”cc1″ ></ContentControl>
    </UserControl.Resources>
    <Grid x:Name=”LayoutRoot”>
        <data:DataGrid AutoGenerateColumns=”False”
                       ItemsSource=”{Binding Path=Customers}” Name=”datagrid1″>
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Width=”150″ Header=”Name”  Binding=”{Binding Name}”/>
                <data:DataGridTemplateColumn Width=”150″ Header=”City”>
                    <data:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox SelectedItem=”{Binding City}”
                                      ItemsSource=”{Binding Source={StaticResource cc1}, Path=DataContext.Cities}” ></ComboBox>
                        </DataTemplate>
                    </data:DataGridTemplateColumn.CellTemplate>
                </data:DataGridTemplateColumn>
            </data:DataGrid.Columns>
        </data:DataGrid>
    </Grid>
</UserControl>

Here is what it looks like.

nestedbindings

Categories: Sivlerlight 3

Alignment of label in Dataform

August 10, 2009 lee Leave a comment

One of the forum users was looking to align the label in the Datafield of DataForm with the following code

<dataFormToolkit:DataField>
    <dataFormToolkit:DataField.Label>
        <TextBlock Text=”Categories” VerticalAlignment=”Top” />
    </dataFormToolkit:DataField.Label>
    <Grid>
        <StackPanel x:Name=”listCategories” />
    </Grid>
</dataFormToolkit:DataField>

sure enough, it doesnt work. I am not sure if there is  easier way, but styling the Label does work, changes made to the default style in bold

Alignment

<Style x:Key=”LabelStyle1″ TargetType=”dataInput:Label”>
         <Setter Property=”IsTabStop” Value=”False”/>
         <Setter Property=”Template”>
          <Setter.Value>
           <ControlTemplate TargetType=”dataInput:Label”>
            <StackPanel Orientation=”Horizontal”>
             <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name=”CommonStates”>
               <VisualState x:Name=”Normal”/>
               <VisualState x:Name=”Disabled”/>
              </VisualStateGroup>
              <VisualStateGroup x:Name=”ValidationStates”>
               <VisualState x:Name=”Valid”/>
               <VisualState x:Name=”Invalid”/>
              </VisualStateGroup>
              <VisualStateGroup x:Name=”RequiredStates”>
               <VisualState x:Name=”NotRequired”/>
               <VisualState x:Name=”Required”>
                <Storyboard>
                 <ObjectAnimationUsingKeyFrames Duration=”0″ Storyboard.TargetName=”ContentControl” Storyboard.TargetProperty=”FontWeight”>
                  <DiscreteObjectKeyFrame KeyTime=”0″ Value=”SemiBold”/>
                 </ObjectAnimationUsingKeyFrames>
                </Storyboard>
               </VisualState>
              </VisualStateGroup>
             </VisualStateManager.VisualStateGroups>
             <Border Background=”{TemplateBinding Background}” BorderBrush=”{TemplateBinding BorderBrush}”
       BorderThickness=”{TemplateBinding BorderThickness}” CornerRadius=”2″ Padding=”{TemplateBinding Padding}” VerticalAlignment=”Top”>
              <ContentControl x:Name=”ContentControl” FontFamily=”{TemplateBinding FontFamily}”
        FontSize=”{TemplateBinding FontSize}” FontStretch=”{TemplateBinding FontStretch}” FontWeight=”{TemplateBinding FontWeight}”
        HorizontalContentAlignment=”{TemplateBinding HorizontalContentAlignment}”
        IsTabStop=”False” VerticalContentAlignment=”{TemplateBinding VerticalContentAlignment}”
        Cursor=”{TemplateBinding Cursor}” HorizontalAlignment=”{TemplateBinding HorizontalAlignment}”
        VerticalAlignment=”{TemplateBinding VerticalAlignment}” Content=”{TemplateBinding Content}”
        ContentTemplate=”{TemplateBinding ContentTemplate}” Foreground=”{TemplateBinding Foreground}”/>
             </Border>
            </StackPanel>
           </ControlTemplate>
          </Setter.Value>
         </Setter>
        </Style>

<dataFormToolkit:DataField   LabelStyle=”{StaticResource LabelStyle1}”  >
           <dataFormToolkit:DataField.Label>                               
                    <TextBlock Text=”Categories”  />                               
           </dataFormToolkit:DataField.Label>
           <Grid>
              <StackPanel x:Name=”listCategories”>
                 <CheckBox Content=”Checkbox1″/>
                 <CheckBox Content=”Checkbox2″/>
                 <CheckBox Content=”Checkbox3″/>
                 <CheckBox Content=”Checkbox4″/>
                 <CheckBox Content=”Checkbox5″/>
               </StackPanel>
            </Grid>
</dataFormToolkit:DataField>

Categories: Sivlerlight 3

Working with DataForm

July 27, 2009 lee 3 comments

Dataform has changed a lot in the RTM version from the beta and my previous post on DataForm is no longer valid now.
Here is something I did earlier.

I created EF model using Northwind database and added DomainService. To start with simple form. I started with Categories(Add/Edit)

so I created a Dataform with ReadOnlyTemplate and EditTemplate

Only the NavigationButtons are enabled. so we can navigate to an item, click ‘edit’ where we can edit the item and save/cancel.
We can also add a Category by clicking the Add button

<dataFormToolkit:DataForm Width=”400″ Height=”400″ AutoEdit=”False”  x:Name=”dataform1″  CommandButtonsVisibility=”Navigation”>
            <dataFormToolkit:DataForm.ReadOnlyTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Width=”Auto” Orientation=”Horizontal”>
                            <Button Content=”Add New” Click=”AddButton_Click”/>
                        </StackPanel>
                        <dataFormToolkit:DataField Label=”Category Name:”>
                            <TextBlock Text=”{Binding CategoryName}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”Description:”>
                            <TextBlock Text=”{Binding Description}”/>
                        </dataFormToolkit:DataField>
                        <StackPanel Width=”Auto” Orientation=”Horizontal”>
                            <Button Width=”100″ Height=”28″ Content=”Edit” Click=”EditButton_Click”/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </dataFormToolkit:DataForm.ReadOnlyTemplate>
            <dataFormToolkit:DataForm.EditTemplate>
                <DataTemplate>
                    <StackPanel>
                        <dataFormToolkit:DataField Label=”Category Name:”>
                            <TextBox Text=”{Binding CategoryName, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”Description:”>
                            <TextBox Text=”{Binding Description, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <StackPanel Width=”Auto” Orientation=”Horizontal”>
                            <Button Width=”100″ Height=”28″ Content=”Save” Click=”SaveButton_Click”/>
                            <Button Width=”100″ Height=”28″ Content=”Cancel” Click=”CancelButton_Click”/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </dataFormToolkit:DataForm.EditTemplate>
        </dataFormToolkit:DataForm>

 That was pretty simple. what if the dataform is bit more complex with a combobox, AutocompleteBox etc.
 products table has got a couple of columns that have look ups and is close to real scenario

 <dataFormToolkit:DataForm x:Name=”dataform1″ AutoEdit=”True” AutoGenerateFields=”False”>
            <dataFormToolkit:DataForm.EditTemplate>
                <DataTemplate>
                    <StackPanel>                       
                        <dataFormToolkit:DataField Label=”ProductName:”>
                            <TextBox Text=”{Binding ProductName, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”Category:”>
                            <ComboBox x:Name=”cbCategory” DisplayMemberPath=”CategoryName”
                                      SelectedItem=”{Binding Category, Mode=TwoWay}” />
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField >
                            <CheckBox Content=”Discontinued” IsChecked=”{Binding Discontinued, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”QuantityPerUnit:”>
                            <TextBox Text=”{Binding QuantityPerUnit, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”Supplier:”>
                            <input:AutoCompleteBox x:Name=”acb1″ SelectedItem=”{Binding Suppliers, Mode=TwoWay}”
                                                   ItemTemplate=”{StaticResource dt}” FilterMode=”StartsWith”   
                                                   MinimumPrefixLength=”1″  ></input:AutoCompleteBox>
                           
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”UnitPrice:”>
                            <TextBox Text=”{Binding UnitPrice, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”UnitsInStock:”>
                            <TextBox Text=”{Binding UnitsInStock, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <dataFormToolkit:DataField Label=”UnitsOnOrder:”>
                            <TextBox Text=”{Binding UnitsOnOrder, Mode=TwoWay}”/>
                        </dataFormToolkit:DataField>
                        <StackPanel Width=”Auto” Orientation=”Horizontal”>
                            <Button Width=”100″ Height=”28″ Content=”Save” Click=”SaveButton_Click”/>                           
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </dataFormToolkit:DataForm.EditTemplate>
        </dataFormToolkit:DataForm>

 <DataTemplate x:Key=”dt”>
            <TextBlock Text=”{Binding CompanyName}”/>
        </DataTemplate>

I defined a Dataform to Add/edit a product with a combobox for Categories and AutoCompleteBox for picking a supplier.
the main change was to set the ItemSource properties of the ComboBox and AutoCompleteBox in the ContentLoaded handler

 void dataform1_ContentLoaded(object sender, DataFormContentLoadEventArgs e)
        {
            ComboBox cb = dataform1.FindNameInContent(“cbCategory”) as ComboBox;
            cb.ItemsSource = ctx.Categories;
            acb = (dataform1.FindNameInContent(“acb1″) as AutoCompleteBox);
            acb.ItemsSource = ctx.Suppliers;
            acb.ItemFilter = (searchText, item) => {
                if ((item as Suppliers).CompanyName.ToLower().StartsWith(searchText.ToLower()))
                {                   
                    return true;
                }
                else
                    return false;
                };
        }

I was not able to set the Text that is displayed when you select a supplier in the AutoCompleteBox.
So I created a Suppliers.shared.cs class in the WebProject which basically overrides ToString implementation. so when the supplier is picked, we get the value we want rather than ‘Suppliers :6′ or something like that

 public partial class Suppliers
    {
        public override string ToString()
        {
            return this.CompanyName + ” (” + this.City + “)”;
        }
    }

you can download the code  here

Change the connectionstring in Web.config as  applicable.

By default the startpage is MainPage.xaml.  To view/edit products, make sure you modify App.xaml.cs  to use “products.xaml” for the RootVisual”

Categories: Sivlerlight 3

Hilighting entire row in datagrid

June 29, 2009 lee 4 comments

when we select a row in datagrid the entire row will be highlighted along the the cell we clicked on getting a different background. when our datagrid is readonly we may not want this special treatment for the current cell. we could style the cell to remove this highlight. Here is the image of the selectedrow before and after applying the style

datagridselectionremoved1
 <Style x:Key=”dgc” TargetType=”data:DataGridCell”>
            <Setter Property=”Background” Value=”Transparent” />
            <Setter Property=”HorizontalContentAlignment” Value=”Stretch” />
            <Setter Property=”VerticalContentAlignment” Value=”Stretch” />
            <Setter Property=”Cursor” Value=”Arrow” />
            <Setter Property=”IsTabStop” Value=”False” />
            <Setter Property=”Template”>
                <Setter.Value>
                    <ControlTemplate TargetType=”data:DataGridCell”>
                        <Grid Name=”Root” Background=”{TemplateBinding Background}”>
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name=”CurrentStates”>
                                    <vsm:VisualState x:Name=”Regular” />
                                    <vsm:VisualState x:Name=”Current”>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName=”FocusVisual” Storyboard.TargetProperty=”Opacity” To=”1″ Duration=”0″ />
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name=”ValidationStates”>
                                    <vsm:VisualStateGroup.Transitions>
                                        <vsm:VisualTransition GeneratedDuration=”00:00:0.1″/>
                                    </vsm:VisualStateGroup.Transitions>
                                    <vsm:VisualState x:Name=”Valid”/>
                                    <vsm:VisualState x:Name=”Invalid”>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName=”InvalidVisualElement” Storyboard.TargetProperty=”Opacity” Duration=”0″ To=”1″/>
                                            <ColorAnimation Storyboard.TargetName=”FocusVisual” Storyboard.TargetProperty=”(Fill).Color” Duration=”0″ To=”#FFFFFFFF”/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width=”Auto” />
                            </Grid.ColumnDefinitions>

                            <Rectangle Name=”FocusVisual” Stroke=”#FF6DBDD1″ StrokeThickness=”1″ Fill=”#66FFFFFF” HorizontalAlignment=”Stretch”
                                   VerticalAlignment=”Stretch” IsHitTestVisible=”false” Opacity=”0″ />

                            <ContentPresenter
                            Content=”{TemplateBinding Content}”
                            ContentTemplate=”{TemplateBinding ContentTemplate}”
                            Cursor=”{TemplateBinding Cursor}”
                            HorizontalAlignment=”{TemplateBinding HorizontalContentAlignment}”
                            VerticalAlignment=”{TemplateBinding VerticalContentAlignment}”
                            Margin=”{TemplateBinding Padding}” />

                            <Rectangle x:Name=”InvalidVisualElement” IsHitTestVisible=”False” StrokeThickness=”1″ Stroke=”#FFDC000C” HorizontalAlignment=”Stretch” VerticalAlignment=”Stretch” Opacity=”0″/>

                            <Rectangle Name=”RightGridLine” Grid.Column=”1″ VerticalAlignment=”Stretch” Width=”1″ />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

The only change  we need to make is to delete the storyboard from the default style. The style is applied like this

<data:DataGrid Margin=”10″ Width=”200″ x:Name=”datagrid2″ CellStyle=”{StaticResource dgc}” ></data:DataGrid>

Categories: Sivlerlight 3

Resizing Childwindow

June 22, 2009 lee 3 comments

Resizing of the childwindows is not supported in silverlight 3 beta which might be possible in the RTM version, but until then here is one way we can style it and get the resizing to work

I took the style of the ChildWindow and added  a Canvas in the style and added 4 thumbs one on each side of the window. Their size is .5px. so  they dont change the look of the childwindow. when you mouse over near the borders you can see the visual cue from the cursors,  The dragDelta event is handled to resize the window.

we can follow the same logic to get the resize behavior to work with Floatable window

you can see a sample here and download the code here

Categories: Sivlerlight 3