0

Is there a more efficient way of writing following XAML code? (when I say more efficient i meant less repetitive). Especialy with the Hyperlinks and the Expanders. Thank you!

<Window x:Class="InterfazOhmio.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Background>
        <ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
    </Window.Background>
    <Grid>       
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ListBox ScrollViewer.VerticalScrollBarVisibility="Auto">
            <ListBox.Resources>
                <Style TargetType="{x:Type Expander}">
                    <Setter Property="IsExpanded"
           Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                </Style>
            </ListBox.Resources>
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <ItemsPresenter/>
                </ControlTemplate>
            </ListBox.Template>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <ContentPresenter Content="{TemplateBinding Content}"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>            

            <Expander Margin="2" Background="OliveDrab">                
                <Expander.Header>
                    <BulletDecorator>
                        <BulletDecorator.Bullet>
                            <Image Source="Iconos/Pedidos.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />                            
                        </BulletDecorator.Bullet>                        
                        <TextBlock Margin="10,0,0,0" Text="Pedidos" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                    </BulletDecorator>
                </Expander.Header>
                <WrapPanel>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Nuevo Pedido"/>
                        </Hyperlink>
                    </Label>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Consultar Pedidos" />
                        </Hyperlink>
                    </Label>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Pedidos Pendientes" />
                        </Hyperlink>
                    </Label>                                 
                </WrapPanel>
            </Expander>

            <Expander Margin="2" Background="OrangeRed">
                <Expander.Header>
                    <BulletDecorator>
                        <BulletDecorator.Bullet>
                            <Image Source="Iconos/Remitos.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
                        </BulletDecorator.Bullet>
                        <TextBlock Margin="10,0,0,0" Text="Remitos" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                    </BulletDecorator>
                </Expander.Header>
                <WrapPanel>                    
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Nuevo Remito"/>
                        </Hyperlink>
                    </Label>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Consultar Remitos" />
                        </Hyperlink>
                    </Label>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Remitos Pendientes" />
                        </Hyperlink>
                    </Label>
                </WrapPanel>
            </Expander>

            <Expander Margin="2" Background="Teal">
                <Expander.Header>
                    <BulletDecorator>                        
                        <BulletDecorator.Bullet>
                            <Image Source="Iconos/Facturas.png" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
                        </BulletDecorator.Bullet>
                        <TextBlock Margin="10,0,0,0" Text="Facturas" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                    </BulletDecorator>
                </Expander.Header>
                <StackPanel>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Nueva Factura"/>
                        </Hyperlink>
                    </Label>
                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                        <Hyperlink TextDecorations="None">
                            <TextBlock Foreground="White" Text="Consultar Facturas" />
                        </Hyperlink>
                    </Label>                    
                </StackPanel>
            </Expander>          

        </ListBox>        
    </Grid>    
</Window>

UPDATE

Ok, i try suggested solution and it work, but there are some small visual differences in the result as can be seen on the then pictures:

Small Differences

On the left the original menú. On the right the new one with the viewModel:

  • Select item get marked, not in the original menu.
  • Width of the expander is too short

This is the result XAML:

<Window x:Class="InterfazOhmio.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:InterfazOhmio"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Window.Background>
        <ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
    </Window.Background>
    <Grid>       
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ListBox ItemsSource="{Binding myMenu}">
            <ListBox.Resources>
                <Style TargetType="{x:Type Expander}">
                    <Setter Property="IsExpanded"
           Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                </Style>
            </ListBox.Resources>
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <ItemsPresenter/>
                </ControlTemplate>
            </ListBox.Template>

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Expander Margin="2" Background="{Binding Color}">
                        <Expander.Header>
                            <BulletDecorator>
                                <BulletDecorator.Bullet>
                                    <Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
                                </BulletDecorator.Bullet>
                                <TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                            </BulletDecorator>
                        </Expander.Header>
                        <ListBox ItemsSource="{Binding Options}" Background="Transparent">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                                        <Hyperlink TextDecorations="None">
                                            <TextBlock Foreground="White" Text="{Binding}"/>
                                        </Hyperlink>
                                    </Label>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </Expander>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>    
</Window>

Can anybody help me tih this? Thanks! UPDATE II

Almost got it!!!

XAML:

<Window x:Class="InterfazOhmio.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:InterfazOhmio"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Window.Background>
        <ImageBrush ImageSource="Imagenes/background.jpg"></ImageBrush>
    </Window.Background>
    <Grid>       
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <ItemsControl ItemsSource="{Binding myMenu}">
            <ItemsControl.Resources>
                <Style TargetType="{x:Type Expander}">
                    <Setter Property="IsExpanded"
           Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                </Style>
            </ItemsControl.Resources>
            <ItemsControl.Template>
                <ControlTemplate TargetType="{x:Type ItemsControl}">
                    <ItemsPresenter/>
                </ControlTemplate>
            </ItemsControl.Template>

            <ItemsControl.ItemTemplate>
                <DataTemplate>                    
                    <Expander Margin="2" Width="196" Background="{Binding Color}">                        
                        <Expander.Header>
                            <BulletDecorator>
                                <BulletDecorator.Bullet>
                                    <Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
                                </BulletDecorator.Bullet>
                                <TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                            </BulletDecorator>
                        </Expander.Header>
                        <ItemsControl ItemsSource="{Binding Options}" Background="Transparent" BorderThickness="0">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                                        <Hyperlink TextDecorations="None">
                                            <TextBlock Foreground="White" Text="{Binding}"/>
                                        </Hyperlink>
                                    </Label>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Expander>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>    
</Window>

I replace the listbox with ItemsControl. The only thing that is not working now is that only one expander should by expanded at a time. I guess the problem is this code:

         <ItemsControl.Resources>
                <Style TargetType="{x:Type Expander}">
                    <Setter Property="IsExpanded"
           Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                </Style>
            </ItemsControl.Resources>
            <ItemsControl.Template>
                <ControlTemplate TargetType="{x:Type ItemsControl}">
                    <ItemsPresenter/>
                </ControlTemplate>
            </ItemsControl.Template>

Because it points to ListBoxItem class. The problem is that ItemsControlItem class doens´t exist. Is the only problem right now!!!

4
  • 2
    This may be a little more suited for CodeReview or Programmers but will take a look anyway since this sort of thing is fun. Commented Apr 2, 2014 at 19:39
  • For hiding the selection, I found this (see the updated part of the answer on setting ListBoxItem style resources): stackoverflow.com/questions/3351904/… for the width, set HorizontalContentAlignment="Center" on the listbox --- you may also want to set BorderThickness="0" on the innermost listbox (subitems) Commented Apr 3, 2014 at 14:26
  • feel free to move your update into to my answer to keep it a more defined Q&A Commented Apr 3, 2014 at 14:28
  • From what I've found, an ItemsControl does not track the SelectedItem and that's what you're using as the trigger to be expanded. Commented Apr 3, 2014 at 14:57

1 Answer 1

6

It could be done with a ViewModel and then xaml is down to a single item as the template:

Setting the context to the VM

<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>

quick and dirty VM and model

public class ViewModel
{
    public ObservableCollection<Item> Items { get; set; }

    public ViewModel()
    {
        Items = new ObservableCollection<Item>() { new Item() { Title="Pedidos", ImageSource="Iconos/Pedidos.png", Color=new SolidColorBrush(Colors.OliveDrab), Options = new List<string>(){"Nuevo Pedido","Consultar Pedidos","Pedidos Pendientes"} },
                                                   new Item() { Title="Remitos", ImageSource="Iconos/Remitos.png", Color=new SolidColorBrush(Colors.OrangeRed), Options = new List<string>(){"Nuevo Remito","Consultar Remitos","Remitos Pendientes"} },
                                                   new Item() { Title="Facturas", ImageSource="Iconos/Facturas.png", Color=new SolidColorBrush(Colors.Teal), Options = new List<string>(){"Nuevo Factura","Consultar Facturas"} } };
    }
}
public class Item
{
    public string Title { get; set; }
    public List<string> Options { get; set; }
    public SolidColorBrush Color { get; set; }
    public string ImageSource { get; set; }

}

and then the XAML...

ItemsSource

<ListBox ItemsSource="{Binding Items}">

ItemTemplate

       <ItemsControl.ItemTemplate>
            <DataTemplate>                    
                <Expander Margin="2" Width="196" Background="{Binding Color}">                        
                    <Expander.Header>
                        <BulletDecorator>
                            <BulletDecorator.Bullet>
                                <Image Source="{Binding ImageSource}" Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
                            </BulletDecorator.Bullet>
                            <TextBlock Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
                        </BulletDecorator>
                    </Expander.Header>
                    <ItemsControl ItemsSource="{Binding Options}" Background="Transparent" BorderThickness="0">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Label Margin="20,5,5,5" HorizontalAlignment="Stretch">
                                    <Hyperlink TextDecorations="None">
                                        <TextBlock Foreground="White" Text="{Binding}"/>
                                    </Hyperlink>
                                </Label>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
Sign up to request clarification or add additional context in comments.

2 Comments

This is Just Great! Specilly because in my App i'm traying to follow MVVM pattern so already have a ViewModel! I´ll try it but it looks great! Thank you!!!
I update your answer and post the last update. Almost got it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.