Strange behaviour in the AutoSuggestBox's suggestions list in UWP - c#

I'm experiencing some strange behaviour with the AutoSuggestBox in UWP platform, especially regarding its suggestion list elements.
I want to customize those elements with an hover effect that makes a Button appear when the pointer enters the item template… and I would like also to stretch the item's content through all the available template width.
This is the code for the AutoSuggestBox (sorry for some non-english property name, but I think it isn't important):
<AutoSuggestBox MinWidth="300" Text="{x:Bind ViewModel.TestoRicerca, Mode=TwoWay}" ItemsSource="{x:Bind ViewModel.ListaRicerca, Mode=OneWay}" QueryIcon="Find">
<AutoSuggestBox.ItemTemplate>
<DataTemplate x:DataType="vm:Colore">
<Grid PointerExited="{x:Bind OnExitPointer}" PointerEntered="{x:Bind OnEnterPointer}" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Rectangle Width="30" Height="30" Margin="0,5,15,5" Fill="{x:Bind ColorBrush, Mode=OneWay}" Stroke="LightGray" StrokeThickness="1" RadiusX="2" RadiusY="2" VerticalAlignment="Center"/>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="{x:Bind Nome, Mode=OneWay}" VerticalAlignment="Center" FontWeight="Bold" TextWrapping="Wrap"/>
<TextBlock Text="{x:Bind ColorAsString, Mode=OneWay}" Foreground="LightGray" TextWrapping="Wrap" Margin="0,2,0,0"/>
</StackPanel>
<Button Grid.Column="2" Content="Click here" Visibility="{x:Bind IsHovered, Mode=OneWay}" VerticalAlignment="Center" Click="{x:Bind DisplayDetail}"/>
</Grid>
</DataTemplate>
</AutoSuggestBox.ItemTemplate>
</AutoSuggestBox>
The OnEnterPointer and OnExitPointer functions, placed in the main Grid of the ItemTemplate, should make the Button appear always when the pointer is into the Grid area… but this doesn't happen!
Actually, the OnEnterPointer fires ONLY when the pointer is over the Grid's children!
This is shown here in those photos:
How could I make the hover effect firing in the entire Grid's area?
THe other thing is about stretching the list item's content, as I said before and as you can see in the pictures… in a normal ListView I know how to do it (place a custom Style in ListView.ItemPresenterStyle with the properly Setter), but here it doesn't work somehow, maybe because it isn't a ListViewItem the standard item in that suggestion list…
If you have any idea about this question also, I would like to know it.
I thank you for your attention and your patience.
Best regards

Related

Binding StaticResourse Key in uwp

i am trying to refix the hamburger menu with some FontAwesome Icons, my way to do this is a ResourseDictionoary in my app. Now i want to bind the keyFontAwesomeUserString for the glyph bellow . My property in the object is Icon with type string. In my list the Icon var of x:DataType="local:MenuItem" has the values from my resoursedictionary.
<FontIcon Grid.Column="0" FontFamily="{StaticResource FontAwesomeFontFamily}" Glyph="{StaticResource FontAwesomeUserString}" Foreground="White" />
<TextBlock Grid.Column="1" Text="{x:Bind Name, Mode=OneWay}" TextWrapping="Wrap" FontSize="16" VerticalAlignment="Center" Foreground="White"/>
Please tell me if/how i can bind the ResourceKey property of StaticResourse.
Thank you
You can change the values of a resource dictionary by replacing them through code like:
Application.Current.Resources["FontAwesomeUserString"] = "&glyphCode";
Do not forget that StaticResource are only read when the page is created.
Depending when you are updating your dictionary, it could be enough but if you want your application to properly update itself when you are changing something in the resource dictionary, you will have to use ThemeResource.
You can get more details about ThemeResource here.
<FontIcon Grid.Column="0"
FontFamily="{ThemeResource FontAwesomeFontFamily}"
Glyph="{ThemeResource FontAwesomeUserString}"
Foreground="White" />
Update
If you are just trying to set the glyph/font family for all your items, a regular binding is enough:
<DataTemplate x:Key="DefaultTemplate" x:DataType="local:MenuItem">
<Grid Width="240" Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FontIcon Grid.Column="0" FontFamily="{x:Bind FontFamily}" Glyph="{x:Bind Icon}" Foreground="White" />
<TextBlock Grid.Column="1" Text="{x:Bind Name, Mode=OneWay}" TextWrapping="Wrap" FontSize="16" VerticalAlignment="Center" Foreground="White"/>
</Grid>
</DataTemplate>
You just have to define the FontFamily and the Icon in your view mod.
el
You can have a look at the hamburger menu from the UWP toolkit documentation

Layout of list with different elements type in WPF

I need to fix a list with elements that have different types. Each of the type has it's own datatype to represent the viewmodel for each type. The following code works for me, but for some reason the data inside gets truncated, to some value (looks like default). I need to remove this trancation.
Here is what I have. This code is in the control, that could be placed in a list as well (it could be doubled or tripled). But I Don't think it's relevant.
<ScrollViewer VerticalScrollBarVisibility="Visible">
<ListView DockPanel.Dock="Top" Name="testCaseResultListView"
ItemsSource="{Binding LogItems}"
ItemContainerStyleSelector="{StaticResource fixSideViewLogItemStyleSelector}"
SelectionMode="Single"
>
<ListView.View>
<GridView x:Name="gridView2">
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn CellTemplateSelector="{StaticResource fixSideViewLogItemTemplateSelector}"/>
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
</DockPanel>
fixSideViewLogItemTemplateSelector and fixSideViewLogItemStyleSelector are the selectors, that return different datatypes or styles for each of the type in LogItems. The common datatype is a grid with two columns, but that also seems irrelevent - I tried to put a textbox there, and it still gets truncated.
I would like this column to be stretched to the whole gridView. When I set width, of the column, I see the column resizing, but I want it to occupy the whole space. This should be elastic - if I put one control in the window, it should occupy the whole window, and properly resize (with it's column) when the window is resized. If I put two controls, they should divide the space by halves, and still should be resized when the window is resized.
Any help, tips?
Upd
Here is an example of the template I'm using.
<DataTemplate x:Key="testCaseDataResultTemplate">
<!-- Test case results -->
<Grid Margin="50,0,0,0" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<!--Test case result property-->
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<!--Is retry / Name-->
<RowDefinition />
<!--Test case number-->
<RowDefinition />
<!--Low limit-->
<RowDefinition />
<!--High limit-->
<RowDefinition />
<!--Measured-->
<RowDefinition />
<!--State-->
<RowDefinition />
<!--Test time-->
<RowDefinition />
<!--Comment-->
</Grid.RowDefinitions>
<!--Is retry / Name-->
<Image Grid.Column="0" Grid.Row="0"
Source="..\Resources\retry16.png"
Stretch="None" HorizontalAlignment="Left"
Visibility="{Binding Path=IsRetry, Converter={StaticResource boolToVisibilityConverter}}" />
<TextBlock Text="fh fhgfhg fhfhfhgfhg fhgfhfhgfhgfhgfhgfhgfhgf hgfhgfhgfhgfhgfhg fhfhgfhgf hgfhgfhfhg fhfhgf rdederserswerv 2" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" TextWrapping="Wrap" MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}"/>
<!--Test case number-->
<TextBlock Text="Number:" Grid.Column="0" Grid.Row="1" />
<TextBlock Text="{Binding Path=TestCaseNumber}" Grid.Column="1" Grid.Row="1" />
<!--Low limit-->
<TextBlock Text="Low limit:" Grid.Column="0" Grid.Row="2" />
<TextBlock Text="{Binding Path=TestCaseData.LimitData.LowLimit}" Grid.Column="1" Grid.Row="2" />
<!--High limit-->
<TextBlock Text="High limit: " Grid.Column="0" Grid.Row="3" />
<TextBlock Text="{Binding Path=TestCaseData.LimitData.HighLimit}" Grid.Column="1" Grid.Row="3" />
<!--Measured-->
<TextBlock Text="Measured" Grid.Column="0" Grid.Row="4" />
<TextBlock Text="{Binding Path=MeasuredValue, Converter={StaticResource valasaConverter}}" Grid.Column="1" Grid.Row="4" />
<!--State-->
<TextBlock Text="Passed: " Grid.Column="0" Grid.Row="5" />
<TextBlock Text="{Binding Path=Passed}" Grid.Column="1" Grid.Row="5" />
<!--Test time-->
<TextBlock Text="Test time: " Grid.Column="0" Grid.Row="6" />
<TextBlock Text="{Binding Path=TestTime, StringFormat={}{0:hh':'mm':'ss'.'ff}}" Grid.Column="1" Grid.Row="6" />
<!--Comment-->
<TextBlock Text="{Binding Path=ShortMessage}"
Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="2"
Visibility="{Binding Path=HasComment, Converter={StaticResource boolToVisibilityColConverter}}"
VerticalAlignment="Stretch"
MaxWidth="400"
TextAlignment="Center">
<TextBlock.ToolTip>
<StackPanel>
<TextBlock Text="{Binding Path=FullMessage}"/>
</StackPanel>
</TextBlock.ToolTip>
</TextBlock>
</Grid>
</DataTemplate>
It's a bit messy, but it is very simple. It has two columns - the captions, and the values. These columns are nothing to do with truncation.
I have tried also this template:
<DataTemplate x:Key="testCaseDataResultTemplate">
<TextBlock Text="Long long text goes here...... ->" HorizontalAlignment="Stretch"/>
</DataTemplate>
The text was of course longer :) It was still truncating, so I blame the listView/GridView, but not the inner template.
I think that this issue maybe is that you need to set the ListView.HorizontalContentAlignment to Stretch. Also the item container style and the item template must have the HorizontalAlignment to Stretch and the Width property must be Auto. Hope this tips helps...
EDIT
Also I think the problem could be the width of the GridViewColumn, that fix the items width
to it's own width. If you are using a single column, maybe you can change the ListView to a ListBox or an ItemsControl, just an idea.
I don't know what your templates looks like but I see a problem like this, it normally lies with a TextBlock that isn't wrapping and/or that the TextBlock's width is longer than it's parent.
Cannot say that I solved the puzzle, but at least it works as I expected. I removed the whole definition with GridView and columns inside, and put ItemTemplateSelector directly in ListView.
So my ListView looks now like this:
<ListView DockPanel.Dock="Top" Name="testCaseResultListView"
ItemsSource="{Binding LogItems}"
ItemContainerStyleSelector="{StaticResource fixSideViewLogItemStyleSelector}"
SelectionMode="Single"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemTemplateSelector="{StaticResource fixSideViewLogItemTemplateSelector}">
That did it! Hope that will help to somebody as well.

VisualBrush in DataTemplate doesn't redraw

I have a ListView to display attachments and each attachment has a delete button. When I change the ItemSource for the list (i.e. when viewing another item that has different attachments), the icon for the delete button no longer draws.
Here's the template
<DataTemplate x:Key="attachmentListData">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding Path=filename}" TextDecorations="{Binding Path=deleted, Converter={StaticResource deletedStrikethroughConverter}}" />
</Label>
<Button Grid.Column="1" Visibility="{Binding Path=deleted, Converter={StaticResource attachmentDeleteButtonVisibilityConverter}}" Style="{DynamicResource MetroCircleButtonStyle}" Width="40" Height="40" Click="onDeleteAttachmentClicked">
<Rectangle Fill="Black" Width="15" Height="15">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_close}" Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
</Button>
</Grid>
</DataTemplate>
I've been able to work around the issue by having the appbar_close icon drawn somewhere else in the screen, but having the visibility set to hidden. If the icon isn't somewhere else in the screen, after I change the ItemSource the icon will stop drawing.
Obviously this workaround is hacky, but what is the better way to ensure that the icon still shows up?
I think you are missing the DataType property on the DataTemplate. http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype.aspx. I'd be surprised if this was not giving you a binding error on the line where you're binding button Visibility.
You can set x:Shared=False in appbar_close and also you should use PresentationOptions:Freeze, RenderOptions for performance.
Hope it helps.

Silverlight, itemcontrol LostFocus and GetFocus not firing

Okay, so the situation as like this:
I've got an ItemsControl, which contains several children.
the children are actually a UserControl, this is it's Xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--DAY HEADER-->
<Border x:Name="dayHeader" Height="20" BorderBrush="#B0B6BE" BorderThickness="1" Grid.Row="0" Background="{StaticResource WeekHeader}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center"
TextWrapping="NoWrap" Margin="1.5,0,0,0" Text="18"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center"
TextWrapping="NoWrap" Margin="2,0,0,0" Text="Thuesday" />
</Grid>
</Border>
<!--DAY HOURS-->
<ItemsControl x:Name="dayHours" Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Name="dayHourBorder" Height="30" BorderBrush="#B0B6BE" Width="193" Tag="{Binding Index}" BorderThickness="1,0,1,1" Background="AliceBlue"
MouseLeftButtonDown="dayHourBorder_MouseLeftButtonDown" MouseLeftButtonUp="dayHourBorder_MouseLeftButtonUp"
MouseMove="dayHourBorder_MouseMove" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
IN SHORT
it's a grid that in the first row has a border
and in the second row has an ItemsControl.
Alright now... what i wanna do is, whenever i click between the child ItemControls (day hours) i want them to execute some function on the LostFocus() event and on GotFocus() event.
problem is... they don't fire! and it tried registering to them from every possible angle!
HALP.
UPDATE
I tried executing Focus() on MouseLeftButtonDown, but what happened is, it went straight to OnLostFocus, which is not what i want...
i don't understand it
Here is an overview on focus in Silverlight. The article mentions four conditions that need to be satisfied in order for the control to get focus. You should check those four conditions for your control and it should be fine I suppose.
You should also consider on which element you'd like to receive those events as GotFocus and LostFocus are bubbling events.
I've managed to fix this issue by doing this:
doing: this.Focus();
and then: e.Handled = true;
the problem was that the ItemControl usually can't hold focus, and so the click event bubbles up.
but when i tell him it's Handled, it stops it's bubbling and won't lose the focus.

Grid with an image, textblock, and rectangle, inside a listbox not showing up exactly right

So I have this Xaml inside a ListBox Item Template:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="22" Width="Auto">
<Image Margin="-2,0,0,0" Source="{Binding Path=ADsPath, Converter={StaticResource ImxConverter}}" HorizontalAlignment="Left" Width="22" />
<TextBlock Margin="20,3,0,0" Text="{Binding Path=DisplayValue}" Width="Auto" />
<Rectangle Fill="White" Stroke="White" Margin="-2,0,-2,0.5" VerticalAlignment="Bottom" Height="1" Width="Auto" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
The idea is that the rectangle, provides a thin white line across the bottom of the entire ListBox Item; however, with the Xaml above, it only extends as long as the text, not to the full width of the ListBox.
Setting your width to Auto basically tells it to only be large enough to fit everything inside. I think you need to set your Grid's HorizontalAlignment to Stretch for it to work properly.
Edit:
I did a small sample app. Here's how I would do what you are trying to do:
On your actual listbox, I would have the HorizontalContentAlignment property set to Stretch
and
I would change your Grid to a DockPanel:
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel Height="22" HorizontalAlignment="Stretch">
<Rectangle Fill="White" Stroke="White" Margin="-2,0,-2,0.5" DockPanel.Dock="Bottom" Height="1"/>
<Image Margin="-2,0,0,0" Height="20" DockPanel.Dock="Left" Width="22" />
<TextBlock Margin="20,3,0,0" Text="Daniel Manning" DockPanel.Dock="Left"/>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Have you tried removing Width="Auto"? Auto is saying "only make me as big as I need to be" which, in your case, is determined by the length of the text. The default is "Stretch" which means "hey container, do me a favor and make me as wide as you are".

Categories

Resources