This project is read-only.

Resizable List layout with GridSplitter

May 5, 2014 at 12:59 PM
Edited Jun 30, 2014 at 2:25 PM
List Layout width is set to 170, I needed to make this adjustable width through a dependency property named "ListWidth".
This allowed to have a search text box and resize it to the width of the list.

Like this :
Image

If it can help someone, below the code.

1) Add DoubleToGridLengthConverter.cs file in Windows->Converters
namespace FirstFloor.ModernUI.Windows.Converters
{
 /// <summary>
 /// Convert double to GridLength
 /// </summary>
 [ValueConversion(typeof(Double), typeof(GridLength))]
 internal class DoubleToGridLengthConverter : IValueConverter
 {
   /// <summary>
   /// Converts a value.
   /// </summary>
   /// <param name="value">The value produced by the binding source.</param>
   /// <param name="targetType">The type of the binding target property.</param>
   /// <param name="parameter">The converter parameter to use.</param>
   /// <param name="culture">The culture to use in the converter.</param>
   /// <returns>
   /// A converted value. If the method returns null, the valid null value is used.
   /// </returns>
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
    // check whether a value is given
    if (value != null)
    {
        double i = (double)value;
        GridLength result = new GridLength(i);
        return result;
    }
    else
    {
        throw new ValueUnavailableException();
    }
   }

   /// <summary>
   /// Converts a value.
   /// </summary>
   /// <param name="value">The value that is produced by the binding target.</param>
   /// <param name="targetType">The type to convert to.</param>
   /// <param name="parameter">The converter parameter to use.</param>
   /// <param name="culture">The culture to use in the converter.</param>
   /// <returns>
   /// A converted value. If the method returns null, the valid null value is used.
   /// </returns>
   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
     // check whether a value is given
     if (value != null)
     {
         GridLength g = (GridLength)value;
         return (double)g.Value;
     }
     else
     {
         throw new ValueUnavailableException();
     }
   }
 }
}
2) Add in Assets->Converters.xaml
<converters:DoubleToGridLengthConverter x:Key="DoubleToGridLengthConverter" />

3) Add in ModernTab.cs ( FirstFloor.ModernUI.Windows.Controls)
/// <summary>
/// Identifies the ListWidth dependency property. (170.0 is default value for width)
/// </summary>
public static readonly DependencyProperty ListWidthProperty = DependencyProperty.Register("ListWidth", typeof(Double),
    typeof(ModernTab), new PropertyMetadata(170.0));


/// <summary>
/// Gets or sets the width of the List.
/// </summary>
/// <value>The value of the List.</value>
public Double ListWidth
{
    get { return (Double)GetValue(ListWidthProperty); }
    set {SetValue(ListWidthProperty,value); }
}
4) Change in Themes>ModernTab.xaml

<Style.Triggers>
<Trigger Property="Layout" Value="List">
<Trigger.Setters>
<Setter Property="Template">
 <Setter.Value>
  <ControlTemplate TargetType="controls:ModernTab">
   <Grid>
    <Grid.ColumnDefinitions>
      <!- CHANGE -->
      <!--
      <ColumnDefinition Width="170"/>
      <ColumnDefinition Width="9" />
      <ColumnDefinition />
      -->
     <ColumnDefinition  Width="{Binding Path=ListWidth, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay,
                        Converter={StaticResource DoubleToGridLengthConverter}}" MinWidth="50" />
     <ColumnDefinition Width="1" />
     <ColumnDefinition Width="*"/>

     <!-- END CHANGE -->
    </Grid.ColumnDefinitions>

    <!-- link list -->
    <ListBox x:Name="LinkList" ItemsSource="{TemplateBinding Links}"
             Width="Auto"
             ScrollViewer.HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding DisplayName, Converter={StaticResource ToUpperConverter}}"
                           Margin="10,2,2,2" FontSize="{DynamicResource SmallFontSize}" TextTrimming="CharacterEllipsis" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <!-- seperator -->
    <!-- CHANGE -->
    <!--<Rectangle Grid.Column="1" Fill="{DynamicResource SeparatorBackground}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" />-->
    <GridSplitter Grid.Column="1"  Background="{DynamicResource SeparatorBackground}"
                  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                  ShowsPreview="True"/>
                  <!-- ShowsPreview display preview new size : True/False -->

    <!-- END CHANGE -->
    <!-- content -->
    <controls:ModernFrame Grid.Column="2" Source="{Binding SelectedSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                          ContentLoader="{TemplateBinding ContentLoader}" Margin="32,0,0,0" />
   </Grid>
  </ControlTemplate>
 </Setter.Value>
</Setter>
</Trigger.Setters>
</Trigger>
</Style.Triggers>

5 ) Usage
<mui:ModernTab SelectedSource="/2" Layout="List"  x:Name="tabList" Height="256" ListWidth="110">
You can retrieve ListWidth in this way :
<TextBox Width="{Binding ElementName=tabList, Path=ListWidth}"  />
Jun 27, 2014 at 12:07 AM
@macgile

Nice job. Thanks a lot.