UWP app DropDownButton cannot be added to IGridList - xaml

I am trying to create a Flyout menu for each grid cell that opens via dropdown button. However, whatever I try, I cannot get it to work or even build I should say.
My code is
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Label Grid.Column="2" Grid.Row="0" Text="1" />
<Label Grid.Column="3" Grid.Row="0" Text="2" />
<Label Grid.Column="4" Grid.Row="0" Text="3" HorizontalOptions="Start" />
<controls:DropDownButton Grid.Column="4" Grid.Row="0" HorizontalOptions="End"></controls:DropDownButton>
but I get the error
XLS0503 A value of type 'DropDownButton' cannot be added to a collection or dictionary of type 'IGridList1'
Is there some parent element I need to add before?

UWP application doesn't have ViewCell element.
Look for all available GUI and Layout elements in WinUI3 or WinUI2
Read more about WinUI2 here

Related

Image flickers in ListView datatemplate

could someone tell me, how can I avoid image flickering in Datatemplate? Everytime I change the source through binding (MVVM pattern), the image in ListViewItem flickers. For other images in app I've used ImageOpened event in code-behind. But I can't be used when I have DataTemplate.
EDIT:
DataTemplate:
<DataTemplate x:Key="ContactItemDataTemplate" x:DataType="contactData:Contact">
<Grid MinHeight="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="MainImage" Source="{x:Bind ImageStatusUri, Mode=OneWay}" Margin="0,8,12,8">
</Image>
<TextBlock Grid.Column="1" Text="{x:Bind Nickname, Mode=OneWay}" Foreground="Black" TextAlignment="Center"
VerticalAlignment="Center" FontSize="15" HorizontalAlignment="Left"/>
</Grid>
<Rectangle Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" StrokeThickness="0.4" Height="0.4"
VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Stroke="#D1D3D4"/>
</Grid>
</DataTemplate>
type Contact implements INotifyPropertyChanged.
EDIT2:
WriteableBitmap is working, but I have 3 images with scaling factors 100, 200 and 400. It always choose the image with scale 400. When I use normal binding no WriteableBitmap, it take image with scale 100.
The best solution here is for you to sub-class the Image control, overriding the Source property and controlling the transition from one image to another with a flicker-less flow. Learn here: https://mva.microsoft.com/en-US/training-courses/xaml-for-windows-10-controls-14482

Type image not found error in Xamarin.Forms

I have a Forms application, and have ContentPage XAML form.
I try to add an image to this Grid but
this code gives me the error Type image not found.
Note : I had been added this image under Recources and tried also on the root folder.
How can I fix this?
Note2: I had been by right clicked the project and had added image to project.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="1" Grid.Row="0" Grid.Column="0" />
<image Grid.Row="0" Grid.Column="1" source="image2.png"></image>
<Button Text="3" Grid.Row="0" Grid.Column="2" />
</Grid>
XML (and thus XAML) is case-sensitive, so make it <Image> and </Image>.
Like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="1" Grid.Row="0" Grid.Column="0" />
<Image Grid.Row="0" Grid.Column="1" Source="image2.png"></Image>
<Button Text="3" Grid.Row="0" Grid.Column="2" />
</Grid>

ListView - Data template and data source in xaml (instant changes in VS designer)

I have something like this:
<ListView >
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<SymbolIcon Symbol="SomeExistingSymbol" Margin="0,0,10,0" />
<TextBlock Grid.Column="1">Some data</TextBlock>
</Grid>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<SymbolIcon Symbol="SomeExistingSymbol2" Margin="0,0,10,0" />
<TextBlock Grid.Column="1">Some data 2</TextBlock>
</Grid>
<!--More list view items (grids)-->
</ListView>
I don't want to copy Grids over and over. I know I can use binding and data templates.
But I want to have all data defined in xaml - is that possible?
The reason is that I need to see instant changes of data in VS designer, without building project.

UserControl for a Row in a Grid

I have following Grid:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- GridRow-Definition -->
<Label Grid.Row="0" Grid.Column="0">FirstRow:</Label>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Binding_To_First_Row}" />
<Label Grid.Row="1" Grid.Column="0">SecondRow:</Label>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Binding_To_Second_Row}" />
<!-- many more Label-TextBox-Rows -->
</Grid>
Question:
Is there a way to Create a UserControl which contains the Label and TextBox and properly aligns the first Column in a proper way?
The answer is yes, it is possible, but perhaps you should be using a DataGrid or an ItemsControl with a DataTemplate.
The simple answer to your question though is, if you need grid columns in different grids to synchronize their widths, you use the SharedSizeGroup attribute, e.g:
<UserControl>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="column1" Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
</UserControl>
Then in a parent element you use Grid.IsSharedSizeScope="True"
<StackPanel Grid.IsSharedSizeScope="True">
<local:UserControl1/>
<local:UserControl1/>
</StackPanel>
This synchronizes any columns (or rows) that have the same SharedSizeGroup within that scope (you can have multiple nested scopes).

XAML - Can't resize elements to 0 width in this case

Given the following XAML my goal is to keep the columns AAA, BBB, CCC always visible. The columns with the listboxes can resize all the way to zero though.
If I remove the ListBoxes then the application works exactly the way I want it to. That is, it doesn't have the weird behavior where the min widths are not respected.
With the listboxes (or DataGrids) the following XAML has this behavior:
After starting the application, if I drag the splitterA all the way close to BBB (BBB will keep the desired width of 25), then drag the splitterB all the way to the right then AAA will have the desired width of 25.
On the other hand, after starting the application, if I drag splitterA all the way to the right (AAA will keep the desired width of 25), then drag the splitterB all the way to the right then AAA will go off the screen. Surprisingly if I then drag the splitterA just a pixel to the left then both columns will "snap" into the correct place.
<Grid Background="CadetBlue" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
<ColumnDefinition MinWidth="60"/>
</Grid.ColumnDefinitions>
<TextBlock Text="CCC" Width="25" />
<ListBox Grid.Column="1" />
<GridSplitter Width="5" Grid.Column="2" Name="splitterB" HorizontalAlignment="Left" />
<Grid Background="Aqua" Grid.Column="2" Margin="5,0,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
<ColumnDefinition MinWidth="30"/>
</Grid.ColumnDefinitions>
<TextBlock Text="BBB" Width="25" />
<ListBox Grid.Column="1" />
<GridSplitter Width="5" Grid.Column="2" Name="splitterA" HorizontalAlignment="Left" />
<Grid Background="BurlyWood" Grid.Column="2" Margin="5,0,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="AAA" Width="25" />
<ListBox Grid.Column="1" />
</Grid>
</Grid>
</Grid>
Why does it work when I remove the listboxes?
Note: I modified the question and XAML code slightly to clarify things and also to show what I just found about the listboxes.
I've been playing around with the code for a little bit and it looks like your main problem lies in the fact that your GridSplitters don't have their own columns.
The way GridSplitter works is it adjusts the column immediately to the left and immediately to the right of it. So simply adding an additional column for a GridSplitter won't quite cut it, since you will then have 4 columns in your Grid, and you need both columns to the left of the splitter to be affected. So I would recommend putting those in an additional Grid.
The other problem is the MinWidth of 50 you have on the outer grid does not account for the width of the GridSplitter, so it should be 55.
It seems like this whole thing could be done more cleanly, but since I'm not sure exactly what you're trying to accomplish, I kept the "spirit" of your code intact and updated some things:
<Grid Background="CadetBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="50" Width="Auto"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition MinWidth="55" Width="5*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="CCC" />
<ListBox Grid.Column="0"/>
<GridSplitter Width="5" Grid.Column="1" />
<Grid Background="Aqua" Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="25"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition MinWidth="25" Width="5*" />
</Grid.ColumnDefinitions>
<TextBlock Text="BBB"/>
<ListBox Margin="0,20,10,20"/>
<GridSplitter Width="5" Grid.Column="1" />
<Grid Background="BurlyWood" Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="AAA" Width="25" />
<ListBox Margin="0,20,10,20" Grid.Column="1" />
</Grid>
</Grid>
</Grid>
Hope this helps!
It's a WPF bug:
https://connect.microsoft.com/VisualStudio/feedback/details/636072/msdn-forum-grid-layout-issue-with-minwidth-starsizing
http://social.msdn.microsoft.com/Forums/en/wpf/thread/24460784-7d09-4627-89fe-975e0ca7b303
I got around it with a hack. If anyone has a better solution I'd love to hear it...
XAML:
<Grid Background="CadetBlue" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
<ColumnDefinition MinWidth="60"/>
</Grid.ColumnDefinitions>
<TextBlock Text="CCC" Width="25" />
<ListBox Grid.Column="1" />
<GridSplitter Width="5" Grid.Column="2" Name="splitterB" HorizontalAlignment="Left" DragDelta="splitterB_DragDelta" />
<Grid Background="Aqua" Grid.Column="2" Margin="5,0,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Name="bbbColumn"/>
<ColumnDefinition MinWidth="30"/>
</Grid.ColumnDefinitions>
<TextBlock Text="BBB" Width="25" />
<ListBox Grid.Column="1" Name="bbbListBox" />
<GridSplitter Width="5" Grid.Column="2" Name="splitterA" HorizontalAlignment="Left" DragDelta="splitterA_DragDelta" />
<Grid Background="BurlyWood" Grid.Column="2" Margin="5,0,0,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="AAA" Width="25" />
<ListBox Grid.Column="1" />
</Grid>
</Grid>
</Grid>
Code:
private void ToggleWidths()
{
if (bbbColumn.ActualWidth < 10
&& bbbListBox.Visibility != System.Windows.Visibility.Collapsed)
bbbListBox.Visibility = System.Windows.Visibility.Collapsed;
else if (bbbColumn.ActualWidth >= 10
&& bbbListBox.Visibility != System.Windows.Visibility.Visible)
bbbListBox.Visibility = System.Windows.Visibility.Visible;
}
private void splitterA_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
ToggleWidths();
}
private void splitterB_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
ToggleWidths();
}