XAML for a listbox item with a background image

gbzhhu
gbzhhu used Ask the Experts™
on

Hi,

I am developing a Windows Mobile 7 app to mimic an iPhone app I already developed.  I am a C# developer and thought the Apple way would be hard but I found it fairly easy.  Now trying to do the same thing in XAML is a nightmare or I am looking at the wrong things.

I would like to have a listbox with the items having an image as a background and also 4 textblocks.  The list item obvisouly needs to show a click interaction (shows visual change when clicked) which I think is build in.  I am using a button but it hides the textblocks, doesn't scale into the stackpanel I am putting it in.

Attached image for list item background, plus what code I currently have.  Hope someone can do this easily (it is said to be easy but I am finding it hard)

Thanks


<!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
            <Image Source="images/Background@2x.png" Stretch="Fill" Margin="0,0,0,0"/>

            <TextBlock Height="30" HorizontalAlignment="Left" Margin="23,23,0,0" Name="textBlock1" Text="Accounts" VerticalAlignment="Top" Foreground="#FF1D1B1B" />

            <ListBox Grid.RowSpan="2" Height="714" HorizontalAlignment="Left" Margin="0,54,0,0" Name="lstAccounts" VerticalAlignment="Top" Width="480" BorderThickness="1" BorderBrush="Silver"  >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Button Width="460" Height="120"  Margin="0,0,0,0" Padding="0" Click ="Account_Click">
                            <Button.Content>
                                <StackPanel Orientation="Horizontal" Width="400" Height="80" Margin="0" >
                                    <Image Source="images/SingleCellBlue@2x.png" Stretch="Uniform" Margin="0" ></Image>

                                    <StackPanel Orientation="Vertical" Height="80">
                                        <StackPanel Orientation="Horizontal" Height="40">
                                            <TextBlock Width="120" FontSize="20" Text="Number:" Height="40" ></TextBlock>
                                            <TextBlock Width="320" FontSize="20" Text="{Binding Number}" Height="40" ></TextBlock>
                                        </StackPanel>
                                        <StackPanel Orientation="Horizontal" Height="40">
                                            <TextBlock Width="120" FontSize="20" Text="Description:" Height="40" ></TextBlock>
                                            <TextBlock Width="320" FontSize="20" Text="{Binding CompanyName}" Height="40" ></TextBlock>
                                        </StackPanel>
                                    </StackPanel>
                                </StackPanel>
                            </Button.Content>
                        </Button>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>            
        </Grid>
        
    </Grid>

Open in new window

SIngleCellBlue.png
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Hi, you are on the right track (Listbox with ItemTemplate defined).
Few remarks, the image looks nice, but you can also create it in XAML (gradient bruses).

The main problem is that you have a stackpanel which contains the image and the stackpanel.

The width of the button isn't big enough to contain both image and the other stack panel... I would suggest the following:


<Button Width="460" Height="120"  Margin="0,0,0,0" Padding="0" Click="Account_Click">
                            <Grid>
                                <Image Source="SingleCellBlue.png" Stretch="Uniform" Margin="0" />
                                <StackPanel Orientation="Vertical" Height="80">
                                    <StackPanel Orientation="Horizontal" Height="40">
                                        <TextBlock Width="120" FontSize="20" Text="Number:" Height="40" ></TextBlock>
                                        <TextBlock Width="320" FontSize="20" Text="{Binding Number}" Height="40" ></TextBlock>
                                    </StackPanel>
                                    <StackPanel Orientation="Horizontal" Height="40">
                                        <TextBlock Width="120" FontSize="20" Text="Description:" Height="40" ></TextBlock>
                                        <TextBlock Width="320" FontSize="20" Text="{Binding CompanyName}" Height="40" ></TextBlock>
                                    </StackPanel>
                                </StackPanel>
                            </Grid>
                        </Button>

Open in new window

Commented:
And with a gradient brush:


                        <Button Width="460" Height="120"  Margin="0,0,0,0" Padding="0" Click="Account_Click">
                            <Grid>
                                <Border CornerRadius="8" BorderBrush="#6586a4" BorderThickness="1">
                                    <Border.Background>
                                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                            <LinearGradientBrush.GradientStops>
                                                <GradientStop Offset="0" Color="#83b2dc"/>
                                                <GradientStop Offset="0.5" Color="#293f71"/>
                                                <GradientStop Offset="0.5" Color="#1e2f5a"/>
                                                <GradientStop Offset="1" Color="#6d9dc6"/>
                                            </LinearGradientBrush.GradientStops>
                                        </LinearGradientBrush>
                                    </Border.Background>   
                                </Border>
                                
                                <StackPanel Orientation="Vertical" Height="80">
                                    <StackPanel Orientation="Horizontal" Height="40">
                                        <TextBlock Width="120" FontSize="20" Text="Number:" Height="40" ></TextBlock>
                                        <TextBlock Width="320" FontSize="20" Text="{Binding Number}" Height="40" ></TextBlock>
                                    </StackPanel>
                                    <StackPanel Orientation="Horizontal" Height="40">
                                        <TextBlock Width="120" FontSize="20" Text="Description:" Height="40" ></TextBlock>
                                        <TextBlock Width="320" FontSize="20" Text="{Binding CompanyName}" Height="40" ></TextBlock>
                                    </StackPanel>
                                </StackPanel>
                            </Grid>
                        </Button>

Open in new window



The original image had some opacity so you can change the opacity of the boarder I have you if you'd like.



Btw, right now it looks like a Button which contains the Border/Image which inside it you have the text... Wouldn't it be better if the button itself would look like that image (Change the button template... but you will then need to also configure how it will look like when it is pressed, mouse over, etc)

Author

Commented:
Hi Saragani,

That is just brilliant.  Thank you.

I now have the code attached.  I prefer using brushes rather than images, so much easier.  If you could help me a bit further I would appreciate it.

- On clicking the "button" which really is a border with stack panel on top, I would like to make it look as clicked (perhaps draw the border pressed in with a darker colour).  I am assuming I will have to create a style for Listbox itemselected but I have no ideas how to go about that

Thank you
<ListBox Height="714" HorizontalAlignment="Left" Margin="0,54,0,0" Name="lstAccounts" VerticalAlignment="Top" Width="480" BorderThickness="1" BorderBrush="Silver" >
                <ListBox.ItemTemplate> 
                    <DataTemplate>
                        <Grid>
                            <Border CornerRadius="8" BorderBrush="#6586a4" BorderThickness="1" Margin="20,6,0,0">
                                <Border.Background>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <LinearGradientBrush.GradientStops>
                                            <GradientStop Offset="0" Color="#83b2dc"/>
                                            <GradientStop Offset="0.5" Color="#293f71"/>
                                            <GradientStop Offset="0.5" Color="#1e2f5a"/>
                                            <GradientStop Offset="1" Color="#6d9dc6"/>
                                        </LinearGradientBrush.GradientStops>
                                    </LinearGradientBrush>
                                </Border.Background>
                            </Border>

                            <StackPanel Orientation="Vertical" Height="60" Margin="34,10,15,0">
                                <StackPanel Orientation="Horizontal" Height="30">
                                    <TextBlock Width="410" FontSize="20" Text="{Binding CompanyName}" Height="30" Foreground="Black" ></TextBlock>
                                </StackPanel>
                                <StackPanel Orientation="Horizontal" Height="30">
                                    <TextBlock Width="410" FontSize="20" Text="{Binding Number}" Height="30" ></TextBlock>
                                </StackPanel>
                            </StackPanel>
                        </Grid>

                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Open in new window

Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
Ok, so you want a button that looks like the gradient button that I wrote, but still you have a button that surrounds it... Won't it be better if the whole button will look like it?

I also see that you use a ListBox.. List box has a SelectedItem propertym where the selected item is surrounded by a kinda dark bluish color.

If you don't need the selected item feature (for example, you just want to have a list of buttons) then use ItemsControl.

Commented:
Btw, I never worked with Phone-7... I usually program on WPF and sometimes help people on Silverlight. Which architecture is it?? (I remember that it is Silverlight), cause Triggers are for example not well supported on Phone 7.

If triggers are not supported then I would need to use VisualStateManager.
For that I will probably need the System.Windows.Interactactivity and Microsoft.Expression.Interactions dlls (come from Blend).

Will it work?

Author

Commented:
Thank you for your quick response.

What I really would like to display is a list of Accounts (Description and number) in a list so that when clicked I move to the next screen.  This is a WP7 and I am porting the app from iPhone.  iPhone uses UITableView with cells.  I thought the best way to do in WP7 is in a listbox with buttons in it.

How would you go about this (assuming it was WPF windows app)?

BTW, I have Belnd 4 installed and it is meant to help with thisd kind of design but I don't seem to understand how it does things so I am just coding everything in VS2010 pro

Cheers

Commented:
As much as I remember, Phone 7 works with Silverlight, since I remember the funny fact that it still can't show websites that have silverlight in it.

Assuming that you don't need the SelectedItem information then you can replace each of the ListBox tags to ItemsControl.

I'll be back soon with a code that make it a little darker when pressed...

Author

Commented:
>>Assuming that you don't need the SelectedItem information

I will need the SelectedItem in the code behind so that I get the data behind the selected item however I don't need the visual aspect of it

Looking forward to your code and I will try the ItemsControl

Cheers
Commented:
Try this one. I mde an observable collection in the ViewModel so I will have the Items in Binding (ItemsSource="{Binding Items}")


<UserControl x:Class="Silverlight_Q_27042762.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:DesignHeight="300" d:DesignWidth="400">
    
    
    <UserControl.Resources>
        <ControlTemplate x:Key="blueGradientButtonTemplate" TargetType="Button">
            <Grid>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="MouseOver" />
                        <VisualState x:Name="Pressed">
                            <Storyboard>
                                <DoubleAnimation Duration="0" To="0.3" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Disabled">
                            <Storyboard>
                                <DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>

                <Border CornerRadius="8" BorderBrush="#6586a4" BorderThickness="1">
                    <Border.Background>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                            <LinearGradientBrush.GradientStops>
                                <GradientStop Offset="0" Color="#83b2dc"/>
                                <GradientStop Offset="0.5" Color="#293f71"/>
                                <GradientStop Offset="0.5" Color="#1e2f5a"/>
                                <GradientStop Offset="1" Color="#6d9dc6"/>
                            </LinearGradientBrush.GradientStops>
                        </LinearGradientBrush>
                    </Border.Background>
                </Border>

                <!--Border that will make things darker -->
                <Border x:Name="BackgroundAnimation" Background="Black" Opacity="0" IsHitTestVisible="False" CornerRadius="8" />
                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                <!--Border that will make things gray when the button is disabled-->
                <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" />
            </Grid>
        </ControlTemplate>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <ItemsControl Height="714" HorizontalAlignment="Left" Margin="0,54,0,0" Name="lstAccounts" VerticalAlignment="Top" Width="480" BorderThickness="1" BorderBrush="Silver" ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Button Template="{StaticResource blueGradientButtonTemplate}">
                            <StackPanel Orientation="Vertical" Height="60" Margin="34,10,15,0">
                                <StackPanel Orientation="Horizontal" Height="30">
                                    <TextBlock Width="410" FontSize="20" Text="{Binding CompanyName}" Height="30" Foreground="Black" ></TextBlock>
                                </StackPanel>
                                <StackPanel Orientation="Horizontal" Height="30">
                                    <TextBlock Width="410" FontSize="20" Text="{Binding Number}" Height="30" ></TextBlock>
                                </StackPanel>
                            </StackPanel>
                        </Button>
                    </Grid>

                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </Grid>
</UserControl>

Open in new window

Author

Commented:
Thank you saragani

I have it working.  I had to change a bit to suit the WP7.  Changed code attached.  I still kept the Listbox as it allows dragging of items up and down the phone with finger :-)

Now, have you created the style code with VS (typing it yourself) or Blend?  I just know that the next time I try to style a control i will run into a problem.  The code behind is usually not a problem for me in WP7.

Thank you again for helping me.  I couldn't have done without you

Cheers

Commented:
I copy pasted the state manager from a question I've answered few days ago, so not a lot of typing :-)

Author

Commented:
But originally in that question did you type the state manager or did it in Blend?   I am just wondering how people do it.

Commented:
I used blend.

Author

Commented:
Thanks buddy.  I'll need to spend sometime in Blend I think
Dirk HaestProject manager

Commented:
I've requested that this question be closed as follows:

Accepted answer: 500 points for saragani's comment http:/Q_27042762.html#35784563

for the following reason:

This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.

Commented:
Hi, I object!

I was not aware that the author did not give the points to me, but if you read the posts carefully you will see that:

1) The original question was answered on my first 2 posts
2) Not only that I answered his questions, I've kept helping him, beyond the required and helped him with further questions.

Please try to contact the Author so he will know that he should award the points. Anyhow, I'm not seeing any logic in closing this question without awarding any points.

Commented:
Ok, I see that on your last post you are suggesting accepting my answer. Anyhow, It is preferred that the author will close the question.

10x

Author

Commented:
Sorry for accepting this so late.  You did a wonderful job helping me.  I just got sucked into the project

Commented:
Np, I wasn't even aware that the question wasn't closed.

Thank you too :-)

Author

Commented:
saragani

I appreciate your patience and I should have awarded the points which is what I intended to do but I am sure being a developer you can imagine what some projects can do to your mentality :-).  Well done for suggesting that I close the question.  The clean up mod is doing what he/she is supposed to do and I take the full blame in not managing my question timely.

Thank you again and I am sure will be asking you another XAML Q soon

H

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial