WPF Expander Not Expanding - c#

I'd like to create a custom WPF accordion-like control without using WPF toolkit... After some searching it seems like the best approach would be to use an Expander... so I wanted to just see if I could get some sort of basic functionality like getting a row to expand upward to show some content when it is expanded and then to have it collapse and hide that content. It seems like it should be pretty straight-forward but my expander never expands. Here's my basic example:
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="215"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Expander Grid.Row="3" Grid.ColumnSpan="2" Header="More Options" ExpandDirection="Down" Background="Red" IsExpanded="False">
<StackPanel Height="300">
<CheckBox Margin="4" Content="Option 1" />
<CheckBox Margin="4" Content="Option 2" />
<CheckBox Margin="4" Content="Option 3" />
</StackPanel>
</Expander>
</Grid>

Update your RowDefinitions. Currently, the Row that the Expander is in is hard-coded to have a Height of 24. Make it Auto.
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>

Related

How to add images to columns in WPF C# XAML application

I am new to C# and WPF development, and I am working on a program that encodes and decodes bitmaps. I have the following XAML code and its expected output:
<Page x:Class="Thompson_EncodeDecode.BeforeDecoding"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Thompson_EncodeDecode"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="BeforeDecoding">
<Grid Margin="10,0,10,10">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Height="35" Padding="5" Background="White">
<Label VerticalAlignment="Center" Foreground="Black">Before Encoding</Label>
</Border>
<Border Grid.Column="1" Height="35" Padding="5" Background="White">
<Label VerticalAlignment="Center" Foreground="Black"> After Encoding</Label>
</Border>
</Grid>
What I am trying to do is add an image onto both columns of the grid so that I can show that the images are the same, but also below that show what the encoded and decoded message within the bitmap is to show that the encoding is actually working. I am unsure how to add an image to the column without either making the image the background for the grid, and also maintaining the Grid integrity.
Also some extra pointers on how to have the input data shown on the bottom right of the grid column would be helpful too. Most of the Googling I have been doing regarding this particular program has confused me, and I am wondering if there is a standard way of approaching it.
You can achieve this in many ways, one of the way is as follows
<Grid Background="Gray">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- U can move this duplicate code into an usercontrol to reuse-->
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<!--Header-->
<RowDefinition Height="1*"/>
<!--Body-->
<RowDefinition Height="8*"/>
<!--Footer-->
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Content="Header" Grid.Row="0"/>
<Image Grid.Row="1"/>
<Label Content="footer" Grid.Row="2" HorizontalContentAlignment="Right"/>
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<!--Header-->
<RowDefinition Height="1*"/>
<!--Body-->
<RowDefinition Height="8*"/>
<!--Footer-->
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Content="Header" Grid.Row="0"/>
<Image Grid.Row="1"/>
<Label Content="footer" Grid.Row="2" HorizontalContentAlignment="Right"/>
</Grid>
</Grid>

Resizing image makes grid getting out from window

I have a grid containing an Image (with 2 rows top and bot that I will use later) and another grid containing 4 radio button.
When I resize, if the grid's height is greater than image, I have 2 whites rows around the image :
But if the height is smaller, the image is not correctly displayed and my buttons disappear :
What can I do to keep buttons on screen and add white columns right and left to see the entire image ?
There is my code :
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="1"
Source="{Binding Picture}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<Grid Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" Grid.Row="0" Background="Red" Content="Point 1" IsChecked="{Binding SelectedPointIndex, ConverterParameter=1, Converter={StaticResource IndexBooleanConverter}}" />
<RadioButton Grid.Column="1" Grid.Row="0" Background="Green" Content="Point 2" IsChecked="{Binding SelectedPointIndex, ConverterParameter=2, Converter={StaticResource IndexBooleanConverter}}"/>
<RadioButton Grid.Column="1" Grid.Row="1" Background="Blue" Content="Point 3" IsChecked="{Binding SelectedPointIndex, ConverterParameter=3, Converter={StaticResource IndexBooleanConverter}}"/>
<RadioButton Grid.Column="0" Grid.Row="1" Background="Yellow" Content="Point 4" IsChecked="{Binding SelectedPointIndex, ConverterParameter=4, Converter={StaticResource IndexBooleanConverter}}"/>
</Grid>
</Grid>
You have simple layout problem. If you want something to take guaranteed space, use Auto, it take precedence over stars (stars are distributing leftover space, they get nothing if there is none).
You need following layout:
<Grid> <!-- high level container to ensure buttons grid is visible -->
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" /> <!-- this row take precedence over first one -->
</Grid.RowDefinitions>
<Grid Grid.Row="0" ... > <!-- image grid -->
...
<Image ... />
</Grid>
<Grid Grid.Row="1"> <!-- buttons grid -->
...
<RadioButton ... />
</Grid>
</Grid>
And demo
For row with the image set <RowDefinition Height="*"/> instead of <RowDefinition Height="auto"/>. If you would like to leave spaces between image and radio button, I see your additional rows, set its height to fixed size.
Explanation:
'auto' guarantee that row of the grid will has height equals to height of the child content. If you would like to affect to size content via size of the parent control dynamically, you should use 'N*', where N - number.
For instance:
<Grid.RowDefinitions>
<RowDefinition Height="*"/> <!-- 25% of the rest of space -->
<RowDefinition Height="2*"/> <!-- 50% of the rest of space -->
<RowDefinition Height="*"/> <!-- 25% of the rest of space -->
<RowDefinition Height="auto"/> <!-- As result is static value. Height equals to height that's needed to display child content -->
</Grid.RowDefinitions>

make Grid disabled when I hover on an other Grid in a universal app

I want to ask,if this is possible,in my case I have 2 columns and 2 rows,every part contains a Grid like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
</Grid>
<Grid Grid.Column="1" Grid.Row="0">
</Grid>
<Grid Grid.Column="1" Grid.Row="0">
</Grid>
<Grid Grid.Column="1" Grid.Row="1">
</Grid>
</Grid>
I want when I hover on one Grid,the other Grids and their components will be disabled,I have search for a property like "IsEnabled="False"" for Grids,but I didn't found any resources on the net
I have used "IsHitTestVisible="False"" property but it's not the result what I want,
so any help please,to achieve what I want
thanks for Help

DockPanel does not constrain height

I am trying to limit the height of a DockPanel (well the content acually) to the remaining UserControl Height with a ScrollViewer in it to scroll if its too big.
I have a window wich uses a ContentController to hold the different UserControls
<Window>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- 0 Menu -->
<RowDefinition Height="auto"/>
<!-- 1 Header -->
<RowDefinition Height="65"/>
<!-- 2 Content -->
<RowDefinition Height="*"/>
<!-- 3 Space -->
<RowDefinition Height="10"/>
<!-- 4 Status line -->
<RowDefinition Height="auto"/>
<!-- 5 Space -->
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<!--...-->
<ContentPresenter Content="{Binding Path=MainWindowContent}" Grid.Column="0" Grid.Row="2"/>
<!--...-->
</Grid>
</Window>
The UserControl wich I having trouble with is just a search for users and the output of the results. It does look like this:
<UserControl>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="12"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition />
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="25"/>
<RowDefinition Height="auto" />
<RowDefinition Height="10" />
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- input fields -->
<DockPanel Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="6" LastChildFill="True" VerticalAlignment="Stretch" Background="{StaticResource PrimaryCorporateBrush}">
<TextBlock Style="{StaticResource HeadlineOutputLabel}" DockPanel.Dock="Top"/>
<Separator Opacity="0" Height="10" DockPanel.Dock="Top"/>
<TextBlock Visibility="{Binding Path=HasResult, Converter={StaticResource Bool2RevertedVisibility}}" Margin="10" DockPanel.Dock="Top"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding Path=HasResult, Converter={StaticResource Bool2Visibility}}">
<ItemsControl ItemsSource="{Binding Path=Members}" VerticalAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Tag="{Binding}">
<!-- Result Element -->
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Grid>
</Border>
</Grid>
<Grid Grid.Column="3" Grid.Row="1">
<!-- info display -->
</Grid>
</Grid>
</UserControl>
I intent to limit the Results ScrollViewer height to the remaining visible space of the window, and if the results exceed it to display a scrollbar. But right now the DockPanel keeps extending the ScrollViewer and nested ItemsControl height till all elements are placed but does NOT show the ScrollBar.
I am a bit lost here why it does that, shouldn't the DockPanel limit the Height to the visible space? tried it with putting buttons instead of ItemsControl, nothing no ScrollBar.
I found the solution!
Further up in the Grid structure there was a row set to "auto" instead of "*" and ScrollViewer seems to only function properly with latter.

How to Wrap a TextBlock in a Horizontal StackPanel

I have a series of TextBlocks that all need to have their text wrapped, but when placed in a Horizontal StackPanel none of the TextBlock's text is wrapped. Originally I just had a StackPanel of several TextBlocks which worked fine, but I added a bullet to each TextBlock for easier reading, and therefore with my new implementation I lost the wrapping ability
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="•"/>
<TextBlock x:Name="InstructionsTextBlock1" Margin="12,0,12,0" TextWrapping="Wrap"
Text="{Binding Path=LocalizedResources.InstructionsPage_InstructionsTextBlock1, Source={StaticResource LocalizedStrings}}">
<LineBreak></LineBreak>
</TextBlock>
</StackPanel>
How might I wrap the text in the second TextBlock within the Horizontal StackPanel?
I ended up removing the StackPanel implementation all together, and creating a grid whereby I had 2 Columns and enough Rows for each bullet/textblock combination. I then set the first column to a small width, and the other column to the remaining width. I then added each bullet/textblock combination accordingly.
<ScrollViewer>
<Grid Margin="12,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".025*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="•"/>
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="InstructionsTextBlock1" Margin="12,0,12,0" TextWrapping="Wrap"
Text="{Binding Path=LocalizedResources.InstructionsPage_InstructionsTextBlock1, Source={StaticResource LocalizedStrings}}">
<LineBreak></LineBreak>
</TextBlock>
...
</Grid>
</ScrollViewer

Categories

Resources