I have a grid with a text bar on top. This text bar shall show an error text and a "Close" link behind it. As soon as there is enough space, the "Close" text shall follow the error text immediately (upper image). If the grid's width decreases, the error text shall be trimmed, so that the "Close" text is still visible (lower image).
I tried all kinds of things: StackPanels, Grids, DockPanels, Width, MaxWidth,... and it's easy to have the "Close" text at the right edge of the grid, but I didn't succeed with just this requirement.
Here is an example of what I tried:
<DockPanel
<TextBlock
DockPanel.Dock="Left"
FontWeight="Bold"
Text="{Binding ErrorText}"
TextTrimming="CharacterEllipsis">
</TextBlock>
<TextBlock>
<Hyperlink Command="{Binding CloseCmd}">Close</Hyperlink>
</TextBlock>
</DockPanel>
The last element is supposed to fill the remaining space, but the upper textbox does not leave any space left for the "Close" element.
This should give you what you are after:
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
FontWeight="Bold"
Text="This is some text that shall be trimmed if there is not enough room"
TextTrimming="CharacterEllipsis" />
<TextBlock Grid.Column="1">
<Hyperlink>Close</Hyperlink>
</TextBlock>
</Grid>
A colleague has given me a good solution:
<WrapPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" TextTrimming="CharacterEllipsis" Margin="5" Text="{Binding ErrorText}" />
<TextBlock Grid.Column="1" Margin="5" Text="Close" Foreground="Blue" />
</Grid>
The trick seems to be the WrapPanel, although nothing gets wrapped here. I have no clue why this works, but it does.
If I understand all requirements correctly, you should first put the close with dock=right like so:
<DockPanel>
<TextBlock DockPanel.Dock="Right">
<Hyperlink Command="{Binding CloseCmd}">Close</Hyperlink>
</TextBlock>
<TextBlock
FontWeight="Bold"
Text="{Binding ErrorText}"
TextTrimming="CharacterEllipsis">
</TextBlock>
</DockPanel>
Try using a WrapPanel with orientation set to vertical:
<Grid>
<WrapPanel Orientation="Vertical">
<TextBlock TextTrimming="CharacterEllipsis">Some sample text</TextBlock>
<Button>Close</Button>
</WrapPanel>
</Grid>
Related
I'm looking for a way of implementing this kind of separator to the expander component in UWP app:
Any ideas how to do that?
I've managed to create the similar look of the expander, but I don't know how to implement separators?
Also, I would like to learn how to make expanders kind of "push" other components down when I expand them, so they don't overlap with other components, but simply move them.
Here's the XAML code for this expander:
<muxc:Expander x:Name="FontExpander"
x:Uid="FontExpander"
Width="1155"
IsExpanded="True"
Margin="22,323,0,0"
VerticalAlignment="Top"
Grid.Row="2"
Height="380"
HorizontalContentAlignment="Left"
ExpandDirection="Down">
<muxc:Expander.Header>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FontIcon Margin="0,0,12,0"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorPrimaryBrush}"
FontSize="16"
Glyph=""/>
<StackPanel Grid.Column="1"
Margin="0,12"
Orientation="Vertical">
<TextBlock x:Uid="SettingsFontTitle" Style="{StaticResource BodyTextBlockStyle}"/>
<TextBlock x:Uid="SettingsFontDescription"
Style="{StaticResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="WrapWholeWords"/>
</StackPanel>
</Grid>
</muxc:Expander.Header>
<muxc:Expander.Content>
<Grid Margin="-18,-170,-17,-170">
<TextBlock x:Name="SettingsFamily" x:Uid="SettingsFamily" Text="Family" Margin="50,51,1000,286"/>
<ComboBox x:Name="ComboBoxFamily" ItemsSource="{x:Bind Fonts}" Width="200" Margin="950,41,0,0" SelectionChanged="ComboBoxFamily_SelectionChanged" />
<TextBlock x:Name="SettingsStyle" x:Uid="SettingsStyle" Text="Style" Margin="50,106,995,218" Loaded="SettingsStyle_Loaded"/>
<ComboBox x:Name="ComboBoxStyle" Width="200" Margin="950,101,0,0">
<x:String>Regular</x:String>
</ComboBox>
<TextBlock x:Name="SettingsSize" x:Uid="SettingsSize" Text="Size" Margin="50,166,1002,158"/>
<ComboBox x:Name="ComboBoxSize" ItemsSource="{x:Bind FontSizes}" Width="200" Margin="950,161,0,0"/>
<TextBlock x:Name="Text" x:Uid="SettingsText" Text="Hello World! I am so excited to be here!" Margin="62,224,38,126" TextWrapping="Wrap" FontSize="{x:Bind (x:Double)ComboBoxSize.SelectedValue, Mode=OneWay}" TextAlignment="Center"/>
</Grid>
</muxc:Expander.Content>
</muxc:Expander>
Any help would be much appreciated!
A separate can for example be implemented using a Border or a Grid:
<Grid Background="DarkGray" Height="1" />
As a side note, you shouldn't use margins to position your elements. Use an appropriate layout Panel. Using a Grid, you should add ColumnDefinitions and RowDefinitions to it as examplified here.
I want to show an accent color chooser like what is built-in in the system.
When It's in full mode, I want it to appear as tiles with available colors, and when it appears as a drop-down list, I want it to appear as a little square and color name next to it.
The problem is that I don't know how to set two templates for full-mode and drop-down mode.
<ComboBox SelectionChanged="AccentColor_SelectionChanged">
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Yellow" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Yellow" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
<ComboBoxItem>
<ComboBoxItem.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Fill="Blue" Width="20" Height="20"/>
<TextBlock Grid.Column="1" Text="Blue" />
</Grid>
</ComboBoxItem.Content>
</ComboBoxItem>
</ComboBox>
This works only for drop down mode. How can I achieve it? (It's a Windows PHone Runtime app).
normally in wp8 when number of items in a dropdownlist becomes more than 5 items it will automatically turns to a full screen mode.else it will show in just a drop list..
In listpicker there is a property call ExpantionMode..try that or following link will help you..
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868195.aspx
try this..just edit as per your requirement.
I have just pasted my code.
<wpToolkit:ListPicker Name="cmbCountry" Background="#FFF9E2" Foreground="#333333" Grid.Column="0" ExpansionMode="FullScreenOnly" ItemsSource="{Binding Countries}" SelectionChanged="cmbCountry_SelectionChanged_1">
<wpToolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CountryName}" FontSize="20"></TextBlock>
</DataTemplate>
</wpToolkit:ListPicker.ItemTemplate>
<wpToolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<Border BorderBrush="#FFF9E2" BorderThickness="0,0,0,3">
<StackPanel Orientation="Horizontal" Width="425">
<TextBlock Text="{Binding CountryName}" FontSize="35"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</wpToolkit:ListPicker.FullModeItemTemplate>
I have a Grid that I populate with a TextBlock and another Grid, which is initially hidden. Since I have the TextBlock to respond to click events, I only want the method to be called when the user clicks on the text itself, not anywhere in the Grid. This is what my code looks like right now:
<Grid x:Name="LayoutRoot" Height="25">
<TextBlock x:Name="NewLabelButton" Text="Add New" Width="Auto" Foreground="Blue" TextDecorations="Underline" MouseLeftButtonUp="AddNew_OnClick" VerticalAlignment="Center"/>
<Grid x:Name="NewLabelPanel" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="NameBox" TextChanged="NameBox_OnTextChanged" KeyDown="NameBox_OnKeyDown" Grid.Column="0"/>
<Button x:Name="OKButton" Content="OK" Click="OKButton_OnClick" IsEnabled="False" Margin="2,0,0,0" Grid.Column="1"/>
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_OnClick" Margin="2,0,0,0" Grid.Column="2"/>
</Grid>
</Grid>
Which results in the TextBlock spanning the whole width of the Grid, making it clickable from essentially anywhere in the Grid. What I want is for it to only be as wide as it needs to be to display the text (which could vary, so I can't use a static width).
Using a StackPanel instead of a Grid resolves the TextBlock width issue, but then the child Grid doesn't expand to fill the entire StackPanel, which it needs to.
Encapsulating the TextBlock in a StackPanel works, but I'm wondering if there is a better (and more efficient) way of doing it.
<Grid x:Name="LayoutRoot" Height="25">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="NewLabelButton" Text="Add New" Foreground="Blue" TextDecorations="Underline" MouseLeftButtonUp="AddNew_OnClick" VerticalAlignment="Center"/>
</StackPanel>
<Grid x:Name="NewLabelPanel" Visibility="Collapsed">
So my question is this: Is there a better way to do this than with my little StackPanel hack, or is that the only way? Thanks!
Try setting the HorizontalAlignment of the TextBlock to the left of the grid.
<TextBlock x:Name="NewLabelButton" HorizontalAlignment="Left" Text="Add New" Width="Auto" Foreground="Blue" TextDecorations="Underline" MouseLeftButtonUp="AddNew_OnClick" VerticalAlignment="Center"/>
I added a DockPanel to a RadioButton element such that I can distribute the radio button label, a textbox and a button horizontally using 100% of the width.
Using LastChildFill="True"within the DockPanel stretches the last element. This works out nicely if the textbox is the last child in the panel. But, as the button is the last element and has a fixed width, the textbox should be stretched. However, there's no such property like 2ndChildFill="True".
My code looks like this:
<RadioButton HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<DockPanel >
<TextBlock VerticalAlignment="Center">in location:</TextBlock>
<TextBox Grid.Column="1" Margin="10,0,0,0">Path string</TextBox>
<Button HorizontalAlignment="Right"
Margin="10,0,0,0" Padding="3,0">...</Button>
</DockPanel>
</RadioButton>
And it gives me this:
Any ideas, hints to fix this? Many thanks in advance...
You need to set DockPanel.Dock attached property for your elements and leave TextBox as the last element:
<RadioButton HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch">
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left"
VerticalAlignment="Center"
Text="in location:" />
<Button DockPanel.Dock="Right"
Margin="10,0,0,0"
Padding="3,0"
Content="..." />
<TextBox Margin="10,0,0,0">
Path string
</TextBox>
</DockPanel>
</RadioButton>
Accepted answer is fixing your problem but creates another one. If someone uses keyboard (TAB) to navigate through your interface, Button will be focused before TextBox. This could be very annoying on a long run. If you don't want to brake your tab orders use Grid instead of DockPanel:
<RadioButton HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center">in location:</TextBlock>
<TextBox Grid.Column="1" Margin="10,0,0,0">Path string</TextBox>
<Button Grid.Column="2" HorizontalAlignment="Right" Margin="10,0,0,0" Padding="3,0">...</Button>
</Grid>
</RadioButton>
Alternative would be to control tab orders yourself using TabIndex attribute. This can be tricky though, especially when you display your control in a collection.
<RadioButton HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" TabIndex="0">
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Text="in location:" />
<Button DockPanel.Dock="Right" Margin="10,0,0,0" Padding="3,0" Content="..." TabIndex="2"/>
<TextBox Margin="10,0,0,0" TabIndex="1">Path string</TextBox>
</DockPanel>
</RadioButton>
I am trying to get my data to display properly within a GridLayout, which is to be used as a DataTemplate for an Item within ListBox. Here is the code associated with what I am doing:
<Grid Name="FeedItemTemplate">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ProfileImage}" Grid.RowSpan="2" Height="75" Width="75" VerticalAlignment="Center" Margin="1" />
<TextBlock Text="{Binding UserName}" Grid.Column="1" Foreground="#FFC8AB14" FontSize="28" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding TimeStamp}" Grid.Column="2" TextWrapping="Wrap" FontSize="18" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Message}" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" TextWrapping="Wrap" FontSize="24" />
</Grid>
The issue is that using this layout, when TextWrapping is set to Wrap, the Item is displayed correctly, but when scrolling through the ListBox everything is really jittery, you cannot scroll in small increments, and it just jumps all over the place.
Any reason why it does this? As I said, only when TextWrapping is set to Wrap it does this. When its not used, it scrolls fine, but the text is all along one line and off the screen.
Does it keep jumping if you explicitly set the top-level Grid element's width to a fixed size?
For some reason that I do not fully understand, settings the ListBox's ItemsPanel property to a StackPanel might solve your problem:
<UserControl.Resources>
<ItemsPanelTemplate x:Key="MyItemsPanelTemplate">
<StackPanel/>
</ItemsPanelTemplate>
</UserControl.Resources>
...
<ListBox ... ItemsPanel="{StaticResource MyItemsPanelTemplate}"/>
This is a known issue with listbox scrolling in the current ctp when you have variable height items. The workaround for now is to set a fixed height on your listbox item content. You'll probably also notice the scroll bar doesnt properly go to the bottom all the time. The workaround fixes that too.
Reference.