WPF View not hiding main window contents - wpf

I have my main window with a grid (2 rows). Row 0 is bound to a couple of views (showing only relevant xaml code):
<Grid>
<Grid.RowDefinitions>
//definition of 2 rows
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding SelectedViewModel}"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" Margin="40,51,28,0" Width="449">
//definition of 2 buttons
</StackPanel>
</Grid>
while row 1 contains 2 buttons (let's call them A and B). When I click button A, view A is displayed in row 0, when I click button B, the same happens to view B. Each view is just a page with a different colour, so I can be sure the view is actually displayed. Quite simple.
Now I noted that if I insert a label in row 0:
<Grid>
<Grid.RowDefinitions>
//definition of 2 rows
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Content="{Binding SelectedViewModel}"/>
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" Margin="40,51,28,0" Width="449">
<Label Name="MyLabel" Content="Label" HorizontalAlignment="Left" Margin="188,172,0,0" VerticalAlignment="Top" Height="56" Width="135" FontSize="22"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" Margin="40,51,28,0" Width="449">
//definition of 2 buttons
</StackPanel>
</Grid>
the view doesn't cover the label, that remains visible. If I look at the view's properties, its colour is blue and its opacity is set to 100%, so it should cover everything that's displayed on the main window's grid, shouldn't it? What am I doing wrong?
Thanks
Gianni

You are could place the StackPanel containing the Label on top of the ContentControl by changing the order in which they are declared:
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Center" Width="449">
<Label Name="MyLabel" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" Height="56" Width="135" FontSize="22"/>
</StackPanel>
<ContentControl Grid.Row="0">
<StackPanel Background="Red" Opacity="1"/>
</ContentControl>
or by setting a value > 0 for the Panel.ZIndex:
<ContentControl Grid.Row="0" Panel.ZIndex="1">
<StackPanel Background="Red" Opacity="1"/>
</ContentControl>
Panel.ZIndex MS Docs
Please note, it's in Row 0 so it won't cover the contents of Row 1 unless you set Grid.RowSpan="2".

Related

Creating a Table in XAML and populating it with an Array?

If I have a table like the one below:
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" ShowGridLines="True" Width="250" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock FontSize="20" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="0">2005 Products Shipped</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="0">Quarter 1</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="1">Quarter 2</TextBlock>
<TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="2">Quarter 3</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="0">50000</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="1">100000</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="2">150000</TextBlock>
<TextBlock FontSize="16" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="3">Total Units: 300000</TextBlock>
</Grid>
Would I be able to populate it in one go using an array.
For example, if I had an Array containing "Row 1", "Row 2" etc. thru 10 would I be able to populate the first column with those values?
I'm not sure I'm doing a great job of explaining. I know I could do each cell individually, but I want it to cycle through and do all at once?
Thanks
Firstly, consider just using a ListBox or ItemsControl, with a DataTemplate. Define the 2 header rows in a separate grid, and stack this one underneath. The catch with this approach is that you need to define fixed-width columns, since each row will be its own Grid (or actually StackPanel is more performant in this scenario):
<ItemsControl ItemsSource="{Binding TheArray}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="100" Text="{Binding Col1}" />
<TextBlock Width="100" Text="{Binding Col2}" />
<TextBlock Width="100" Text="{Binding Col3}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Secondly, if you need to use a true Grid, then one approach could be to define a Behavior on your Grid. This Behavior class would define an Items dependency property. The dependency property's "changed" handler could then create the TextBlocks (x of them for each cell where x is the number of columns), add them to the Grid, and assign the Grid.Row and Grid.Column properties (and even add the RowDefinitions if necessary).
<Grid>
<i:Interaction.Behaviors>
<my:GridItemsBehavior Items="{Binding TheArray}" />
</i:Interaction.Behaviors>
</Grid>
I wouldn't necessarily recommend the latter approach, because you lose a lot of the power of XAML by creating UI in code-behind.

Autoresize ListBox inside ScrollViewer

In my application I have a Window. It contains a left side menu, a header and a place for content.
This content is being loaded dynamically - a UserControl is put in there. These UserControls are various. From just a TextBlock to quite complex pages. To make sure all the content will be visible I have to wrap it with a ScrollViewer (I mean in MyWindow.xaml). It all works fine until I need to put a ListView in the content.
More or less the code looks like that:
<ScrollViewer> // this is the wrapping viewer actually it's in a different file
<UserControl>
......
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding Entities}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Style="{StaticResource Value}" Text="{Binding WorkOrderNumber}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding ActionType}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StartDate}"/>
<TextBlock Style="{StaticResource Value}" Text="{Binding StopDate}"/>
<Separator/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Whatever.. Grid.Row="0" Grid.Column="1"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource CustomButton}" Content="Previous" />
<Button Style="{StaticResource CustomButton}" Content="Current" />
<Button Style="{StaticResource CustomButton}" Content="Next" />
</StackPanel>
</Grid>
</UserControl>
</ScrollViewer>
The result is that the listbox has no scrollbar and gets vary high. The scrollbar is only at the window's scrollviewer.
So in my UserControl I want:
the buttons always to be at the very bottom
the listbox to fill the whole space left (also to resize along with the window)
avoid hardcoding listbox's height
Is that possible?
Use a DockPanel instead of a Grid. DockPanel has a property called LastChhildFill. It is by default true. If you set your ListBox to be the last Child, it will fill all the space:
<ScrollViewer>
<DockPanel>
<StackPanel DockPanel.Dock="Bottom"
Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Style="{StaticResource CustomButton}"
Content="Previous" />
<Button Style="{StaticResource CustomButton}"
Content="Current" />
<Button Style="{StaticResource CustomButton}"
Content="Next" />
</StackPanel>
<ListView >
</ListView>
</DockPanel>
</ScrollViewer>
But this setting makes the Buttons to disappear. I mean they are always at the Bottom of the ListBox. So maybe you need to remove the ScrollViewer.

Making a WPF TextBox be only as wide as the room it has but expand when the space expands?

Notice how the textbox expands to the right until it has enough horizontal space to fit the content? Well I'd like it to not expand and fit the text with the space it has in the window.
If the windows expands, then the Grid.Column it's in will expand, but the textbox itself should expand to fit. Simple enough?
Any suggestions? This is my first foray into WPF and so far it's been pretty sleek.
Edit: Here's my XAML markup:
<Window x:Class="GameLenseWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="350" MinHeight="450" MinWidth="350">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.15*" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Grid.Row="0" Stretch="Fill" Source="Image/topBarBg.png" />
<StackPanel Orientation="Horizontal" Grid.Row="0">
<TextBlock Text="Platform"
Foreground="White"
FontFamily="Georgia"
FontSize="15"
Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<ComboBox x:Name="cmbPlatform"
Margin="10"
FontFamily="Georgia"
FontSize="15"
MinHeight="30"
MinWidth="140"
VerticalAlignment="Center"
VerticalContentAlignment="Center" SelectionChanged="cmbPlatform_SelectionChanged">
<ComboBoxItem>All Platforms</ComboBoxItem>
<ComboBoxItem>Playstation 3</ComboBoxItem>
<ComboBoxItem>XBox 360</ComboBoxItem>
<ComboBoxItem>Wii</ComboBoxItem>
<ComboBoxItem>PSP</ComboBoxItem>
<ComboBoxItem>DS</ComboBoxItem>
</ComboBox>
</StackPanel>
<Image x:Name="imgAbout" Grid.Row="0" Source="Image/about.png"
Height="16" HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0 0 10 0" />
<ListBox Grid.Row="1" x:Name="lstGames" Background="#343434" Padding="5">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="120" Margin="0 10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Border BorderBrush="#202020" BorderThickness="5" CornerRadius="4" Panel.ZIndex="0">
<Image Grid.Row="0" Grid.Column="0" Source="{Binding ImageUrl}" Stretch="Fill"/>
</Border>
<StackPanel Grid.Row="0" Grid.Column="1" Margin="12 0 0 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Title:" FontFamily="Arial" Foreground="White"/>
<TextBlock Text="{Binding Title}" FontFamily="Arial" Foreground="White" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Release Date:" FontFamily="Arial" Foreground="White" />
<TextBlock Text="{Binding ReleaseDate}" FontFamily="Arial" Foreground="White" />
</StackPanel>
<TextBlock Text="Synopsis" FontFamily="Arial" Foreground="White" />
<TextBox Background="#454545" Text="{Binding Synopsis}" MinHeight="76" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
To get a TextBox to wrap inside a ListBox you can make the following changes:
Set the content of the listbox equal to the width of the listbox using: HorizontalContentAlignment="Stretch".
Disable the horizontal scrollbar of the listbox to prevent listbox from getting the desired size of the controls and preventing the word wrap in your textbox.
Set TextWrapping="Wrap" in the TextBox
Here is the XAML:
<ListBox Grid.Row="1" x:Name="lstGames" Background="#343434" Padding="5"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch" >
</ListBox>
<TextBox Text="{Binding Synopsis}" MinHeight="76" TextWrapping="Wrap" />
I believe you need to set the Margin property of your textbox control. In the designer, you can see little circles around each textbox (and each control when you focus them, for that matter). Click the little circle on the right side of the textbox, to make that control grow marginally with the available space in the current layout control (by clicking the circle, the margin will be added into the XAML).
I don't know if in your image you've already adjusted the window size, but with that image it appears you'll also need to set the width for your textbox.
Does this help?

How keep drop down opened in silverlights ComboBox?

I use ComboBox control as popup. Item for my ComboBox is Grid. There is TreeView control and two Buttons in grid. Items of TreeView are CheckBoxes.
When I click on Buttons or CheckBoxes drop down keeps opened, but when I click on other part of grid drop down i closed.
Is there any way to keep it opened until I click outside of ComboBox?
I have looked a lot in Google, but haven't found anything.
<UserControl.Resources>
<common:HierarchicalDataTemplate x:Key="HierarchicalDataTemplate_AddDivision" ItemsSource="{Binding DivisionIDs}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Click="CheckBox_Click" />
<TextBlock Text="{Binding ToDisplay}"/>
</StackPanel>
</common:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.90*"/>
<RowDefinition Height="0.10*"/>
</Grid.RowDefinitions>
<controls:TreeView Height="250" x:Name="itemsToShow" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="230"
Grid.ColumnSpan="2" ItemTemplate="{StaticResource HierarchicalDataTemplate_AddDivision}" SelectedItemChanged="itemsToShow_SelectedItemChanged" />
<Button Margin="28,0,22,5" Content="Ok" Grid.Row="1" d:LayoutOverrides="Height" Click="OkButton_Click"/>
<Button Margin="23,0,27,5" Content="Cancel" Grid.Column="1" Grid.Row="1" d:LayoutOverrides="Height" Click="CancelButton_Click"/>
</Grid>
And this is ComboBox
<ComboBox Grid.Row="1" Width="100" Height="20" HorizontalAlignment="Left" VerticalAlignment="Top" >
<ComboBox.ItemTemplate>
<DataTemplate>
<my1:ShowDivisions x:Name="ShowDivs" Loaded="ShowDivs_Loaded" ParentComboBox="{Binding ElementName=addStr2}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
It sounds like your buttons are not filling all the space in the dropdown part of the ComboBox.
In that case you just need to have a a clickable object behind the buttons to eat any stray mouse clicks:
Try a rectangle with the background set to Transparent (not just a colour with 0 alpha value, as that is not clickable).
(Make sure the rectangle has IsHittestVisible set as well).

Silverlight/WP7: I want to place an Button after the Listbox element which are data bound

I am fairly new to silverlight. I am developing on the windows phone platform.
I want to place a button at the end of the listbox entries which will be bound to data from the webservice (I am using a listbox template)
List item 1
List item 2
List item 3
List item 4
List item 5
List item 6
List item 7
List item 8
..Button..
I tried number of things of using grid/stackpanel etc to host the button and all my solutions place the button at the bottom of my screen instead of bottom of all the listbox entries which might span multiple screens.
XAML file I have is below. I want to add a button below the "LBoxItems"
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ads" >
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Margin="24,24,0,12"
x:Name="SearchTitle">
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Location}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeLarge}"
Text=" > " />
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Category}" />
</StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}"
Text="{Binding Converter={StaticResource SearchHistoryItemSubTitleConverter}}" />
</StackPanel>
</Grid>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<l:SpinnerControl x:Name="SpinnerControl"
Width="55"
Height="55"
Grid.RowSpan="2" />
<TextBlock x:Name="TxtNoResultsMessage"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="No results found"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.RowSpan="2"
Visibility="Collapsed" />
</Grid>
You could use a ScrollViewer:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="800"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox Grid.Row="0">
</ListBox>
<Button Grid.Row="1" Height="30" Content="Test"></Button>
</Grid>
</ScrollViewer>
Simply divide the Grid inside into two rows, the second one being for the Button.
For your specific case it would be:
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="600"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Sample" Height="30" Grid.Row="1" />
</Grid>
</ScrollViewer>
</Grid>
Of course, you can set the appropriate height depending on your situation.
What you want to do, really is to mix and match different items in the DataTemplate. If you're not really happy with how the other solutions work out I might consider adding a button to the datatemplate, but set its visibility to collapsed. Then for the very last entry, set its visibility to visible.
Either way you are in for a bit of a hack, but this way the button is in your list box. If all the button events point to the same handler, and only one is visible, you should be good to go.
I had the same problem and tried using the ScrollViewer approach, however I couldn't get rid of the 'stuck scrolling' issue until I disabled the vertical scrollbar on the listbox. Maybe this will help others too.

Resources