XAML

Binding a Silverlight DataGrid’s ComboBox To a Model

by JBrooks 31. July 2013 11:49

I have a DataGrid that is bound to my Employee entity and I needed to be able to select his building from a list of buildings in that same model. There is a path to the Employee’s Building through buildingId, but no path to the full list of buildings so it could the source for the ComboBox.

The simple solution was to have the Buildings in a ViewModel and then reference that as a resource in my XAML.  The ViewModel retrieves the data in it’s constructor and it has a property EntitySet<Building> Buildings;

    <UserControl.Resources>
        <vm:BuildingsModel x:Key="buildingsModel"  />
    </UserControl.Resources>

Then on the CheckBox inside the <DataTemplate> I have its ItemSource use the resource.

<ComboBox Name="cb" ItemsSource="{Binding Source={StaticResource buildingsModel}, Path=Buildings}" 
    SelectedValuePath="id" 
    SelectedValue="{Binding Path=buildingId, Mode=TwoWay}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding name, Mode=OneWay}" MinWidth="140" />
                <TextBlock Text="  " />
                <TextBlock Text="{Binding address, Mode=OneWay}" />
                <TextBlock Text=", " />

                <TextBlock Text="{Binding city, Mode=OneWay}" />
                <TextBlock Text=", " />
                <TextBlock Text="{Binding state, Mode=OneWay}" />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
 
 
 

Tags:

Development | Silverlight | XAML

Show Child Count in a DataGrid

by jbrooks 11. March 2013 17:49

I have an application with the following as part of the data model:

image

So an Account can have many Users and a user can belong to many Accounts. I wanted to show the Accounts in a DataGrid along with the number of Users that were linked to that account like show in the 3rd column here:

image

The way I did this is to use a converter to count the number of entities in each Account.xrefAccountsUser set.  The DataGrid is bound to Accounts and the the XAML for the 3rd column is:

<sdk:DataGridTextColumn  Header="Users" 
Binding="{Binding xrefAccountsUsers, Converter={StaticResource setToCountConverter}}"
 />

The converter is where we count up the number of entities in the related entity set (xrefAccountsUsers in this case.)  I could not find a type that I could cast the value to that had a Count property, so I  ended up casting it to IEnumerable and then loop thru the set and I do a count manually.  There should never be very many accounts so performance isn’t an issue.

public class SetToCountConverter : IValueConverter
{
    public object Convert(object value,
                                Type targetType,
                                object parameter,
                                System.Globalization.CultureInfo culture)
    {
        int cnt = 0;
        IEnumerable set = value as IEnumerable;
 
        if (set == null)
            return "0";
 
        foreach (var item in set)
            cnt++;
 
        return cnt.ToString();
    }
 
    public object ConvertBack(object value,
                                Type targetType,
                                object parameter,
                                System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Tags:

Silverlight | Development | XAML

Disable CheckBoxes in Silverlight’s DataGrid

by jbrooks 11. March 2013 12:41

I have an application where the administrator can edit a user’s roles.

image

I wanted to reuse this same grid to show the user what roles they have, but I didn’t want them to be able to change the data. There is a IsReadOnly property on each of the columns, but this still allows the user to change the checkboxes.

If I set the IsEnabled property on the datagrid to false, then the user can’t change the checkboxes but the datagrid looks washed out and hard to read.

image

So this is too washed out to go with.  I realized that another way to disable CheckBoxes is from the style:

<sdk:DataGrid.Resources>
    <Style TargetType="CheckBox">
        <Setter Property="IsThreeState" Value="False" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
</sdk:DataGrid.Resources>

I wanted to see if there was a way to programmatically add a setter to this and there was.

// find the CheckBox style resource.
var resource = dgAccounts.Resources.FirstOrDefault(x => x.Key == typeof(CheckBox));
    
if (resource.Key != null)
{
    Style s = resource.Value as Style;
    
    (s.Setters as SetterBaseCollection).Add(new
    Setter(CheckBox.IsEnabledProperty, value));
}
    

In the code above, “value” can be true or false.  This gives me a little better presentation:

image

But, hey, this is Silverlight – why am I using those dinky check boxes anyway.  The better solution is to create a user control that acts like a checkbox and you can style it as big as you want.

image

And then the code to set the disable style just needs to change the type it is looking for on the 1 line:

var resource = dgAccounts.Resources.FirstOrDefault(x => x.Key == typeof(ucCheckBox));

Now, the disabled version is a lot more readable.

image

Tags:

Development | Silverlight | XAML

Generic Boolean to Text Converter

by JBrooks 20. July 2012 11:52
I’ve seen this done a few different ways, but I think this is the best way because you can reuse it. Below is the converter, notice the 2 public properties.
public class BoolToTextConverter : IValueConverter
{
    public string TrueText { get; set; }
    public string FalseText { get; set; }

    public object Convert(object value, Type targetType, object parameter, 
                                                   System.Globalization.CultureInfo culture)
    {
        return ((bool)value) ? TrueText : FalseText;
    }

    public object ConvertBack(object value, Type targetType, object parameter,
                                                  System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}
Then in your XAML resource section you would set the properties:
<localHelpers:BoolToTextConverter x:Key="boolToTextConverter">
    <localHelpers:BoolToTextConverter.TrueText>
        Sent
    </localHelpers:BoolToTextConverter.TrueText>
    <localHelpers:BoolToTextConverter.FalseText>
        Not Sent
    </localHelpers:BoolToTextConverter.FalseText>
</localHelpers:BoolToTextConverter>
So this is setting the 2 public properties. The final part is to bind this to the TextBox, in this example I’m binding to a boolean property named “sent”. The result is that the text will be “Sent” if it is true and “Not Sent” if it is false.
<TextBlock Text="{Binding Path=sent, Converter={StaticResource boolToTextConverter}}"
            VerticalAlignment="Center" Margin="4"  
            TextAlignment="Center" />

Tags:

Silverlight | Development | XAML

One Script

OneScript Continuous Integration for you database Scripts in version control are automatically combined into a release script.

RecentPosts