Datagrid is glitching and rows are getting Reordered when scrolling upwards - avaloniaui

When I run this, it gets a fairly large list of items. At first scrolling downwards has no issues at all. However when I scroll upwards it starts glitching back and forth and you can never reach the top of the DataGrid. Even more the rows start to get mixed up and no longer sit in the position they're supposed to.
<DataGrid
Grid.Row="1"
CanUserResizeColumns="True"
CanUserReorderColumns="False"
CanUserSortColumns="False"
IsReadOnly="True"
HeadersVisibility="All"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AutoGenerateColumns="False"
GridLinesVisibility="All"
MaxColumnWidth="500"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
Background="{Binding Context.UniversalSettingsContext.BackgroundColor}"
Items="{Binding Context.WorkItemPanelContext.WorkItems}"
>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Allow?">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsThreeState="False" IsChecked="{Binding IsChecked}" HorizontalAlignment="Right"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" />
<DataGridTextColumn Binding="{Binding State}" Header="State" />
<DataGridTextColumn Binding="{Binding Description}" Header="Description" />
<DataGridTextColumn Binding="{Binding ReleaseNotes}" Header="Release Notes" />
</DataGrid.Columns>
</DataGrid>

The binding statement you have:
Context.WorkItemPanelContext.WorkItems
Is suggesting you have an odd structure behind your view. It needs flattening so you are databinding to WorkItems, not Context.WorkItemPanelContext.WorkItems.
Have a read of the Law of Demeter.
I would suggest having a read around MVVM as a design pattern and reorganise your data so it's a much more binding friendly and flatter than it is now.
It looks like you have one god object called Context that has absolutely everything on it which is not a good design choice.
There isn't anything in this code that suggest it should be behaving like this other than the deep binding I've mentioned.

Related

uwp xbox app XYNavigation in Pivot Control

I am an experienced uwp developer but a beginner for uwp xbox platform. I am trying to set the XY Navigation for my app and trying to test it with keyboard (as I don't own a xbox myself).
I am using a Pivot view and I can easily navigate between the pivot items with right and left arrow keys, which makes sense. but when my settings page is selected with pivot option (settings pivot header is focused and settings pivot item is in view) then I try to shift my focus vertically downwards to the first control in the settings page (radio buttons) but I am not able to do it the focus remains on settings header and doesn't shift downward on the page.
So how can I shift the focus downwards from a pivot header to the 1st control within the page on pressing down, and vice versa i.e : when 1st control is focused I should move up to go back to the header of the pivot of that page, because I think that is the traditional navigation with pivot control on uwp xbox right?
Secondly the docs and the xbox app dev videos I watched recommended to set the focus on an element which makes sense, when the app loads, should that be done with this.Focus() method or is there a more efficient way to do it with xaml?
Code:
Pivot.xaml
<Grid x:Name="MainGrid">
<Pivot x:Uid="PivotPage" x:Name="MainPivot" >
<PivotItem x:Uid="PivotItem_OnNow">
<Frame>
<views:OnNowPage/>
</Frame>
</PivotItem>
<PivotItem x:Uid="PivotItem_Guide">
<Frame>
<views:GuidePage/>
</Frame>
</PivotItem>
<PivotItem x:Uid="PivotItem_Settings">
<Frame>
<views:SettingsPage/>
</Frame>
</PivotItem>
</Pivot>
</Grid>
Settings.xaml
<Grid>
<Grid Margin="{StaticResource MediumLeftRightMargin}">
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
x:Uid="Settings_Title"
x:Name="TitlePage"
Style="{StaticResource PageTitleStyle}" />
<StackPanel Grid.Row="1">
<TextBlock
x:Uid="Settings_Personalization"
Style="{StaticResource SubtitleTextBlockStyle}" />
<StackPanel Margin="{StaticResource SettingsSubheaderMargin}">
<TextBlock
x:Uid="Settings_Theme"
Style="{StaticResource BodyTextStyle}" />
<StackPanel Margin="{StaticResource EightTopMargin}">
<RadioButton
x:Uid="Settings_Theme_Light"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Light, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Light</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
<RadioButton
x:Uid="Settings_Theme_Dark"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Dark, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Dark</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
<RadioButton
x:Uid="Settings_Theme_Default"
GroupName="AppTheme"
IsChecked="{x:Bind ViewModel.ElementTheme, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Default, Mode=OneWay}"
Command="{x:Bind ViewModel.SwitchThemeCommand}">
<RadioButton.CommandParameter>
<xaml:ElementTheme>Default</xaml:ElementTheme>
</RadioButton.CommandParameter>
</RadioButton>
</StackPanel>
</StackPanel>
<TextBlock
x:Uid="Settings_About"
Style="{StaticResource SubtitleTextBlockStyle}"/>
<StackPanel Margin="{StaticResource EightTopMargin}">
<TextBlock
Text="{x:Bind ViewModel.VersionDescription, Mode=OneWay}" />
<TextBlock
x:Uid="Settings_AboutDescription"
Margin="{StaticResource EightTopMargin}" />
<HyperlinkButton
x:Uid="Settings_PrivacyTermsLink"
Margin="{StaticResource EightTopMargin}" />
</StackPanel>
</StackPanel>
</Grid>
</Grid>
The MSDN has listed several scenarios that XY navigation might not work the way you expect:
The IsTabStop or Visibility property is set wrong.
The control getting focus is actually bigger than you think—XY navigation looks at the total size of the control (ActualWidth and ActualHeight), not just the portion of the control that renders something interesting.
One focusable control is on top of another—XY navigation doesn't support controls that are overlapped.
If XY navigation is still not working the way you expect after fixing these issues, you can manually point to the element that you want to get focus using the method described in Overriding the default navigation.
Please first check these scenarios, after that, if you still could not solve this issue. Please provide a Minimal, Complete, and Verifiable example. I will help you diagnose it on my side.

How do I create a two column layout using xaml RelativePanel?

I'd really like to use RelativePanel in a UWP app I'm writing, to simplify visual state.
This is what I want
I've tried to achieve this with the following XAML:
<RelativePanel>
<TextBlock x:Name="Title" Height="50" Margin="15" FontSize="24"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
</TextBlock>
<TextBox x:Name="Editor" Margin="15" Padding="20" HorizontalAlignment="Stretch"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.RightOf="FileList">
</TextBox>
<ListView x:Name="FileList" HorizontalAlignment="Stretch" Margin="15"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="Title">
</ListView>
</RelativePanel>
This isn't working. Editor does not stretch. If I set Editor to RelativePanel.AlignRightWith="FilesList", it stretches past files list and fills the window.
Is there any way to do what I want with RelativePanel? Please don't post suggestions on how to do this in Grid, I can already do that - I want to use RelativePanel in this case
Your Editor control should have -
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.LeftOf="FileList"
RelativePanel.AlignBottomWithPanel="True"
Note it should be LeftOf, not RightOf. You will also need AlignBottomWithPanel set to True.

Silverlight Datagrid Column header Text Break Line

I am Using Silverlght 4.I have a datagrid Header whose text="StudentDetailOfAplication".Since It Occupies more length in I need to have a break line near "Application".Please send me some usefull links how to do this
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid AutoGenerateColumns="False" Height="227" HorizontalAlignment="Left" Margin="39,37,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="316" >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="StudenDetailsOFApplication" Width="100" Binding="{Binding id}"></sdk:DataGridTextColumn>
<sdk:DataGridTextColumn Header="Name" Width="100" Binding="{Binding productName}"></sdk:DataGridTextColumn>
<sdk:DataGridTextColumn Header="NumberOfAplication" Width="114" Binding="{Binding qty}"></sdk:DataGridTextColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid></Grid>
Header="Student Details
Of Application" or Header="Student Details
Of Application" will also work. Or if you're not inserting into a string you can also do something like.
<TextBlock>
Line<LineBreak/>Break
</TextBlock>
but personally I just use the codes shown in the first two examples. Also keep in mind the xml will retain whitespace, so you can do like Header=" Details of
Student Application" for alignment purposes if TextAlignment property isnt available. Hope this helps.

Unhandled Error in Silverlight Application Code: 4004 System.Collections.Generic.KeyNotFoundException

I'm getting this error in a very strange manner. I've been able to isolate it, and I know what is causing it, but I don't have a clue why.
This is the situation: I have a ChildWindow, which contains a TabControl, which contains two UserControl, and both of them contain a datagrid like this causing the unhandled error:
<sdk:DataGrid x:Name="PersonEmailDataContainer" AutoGenerateColumns="False" Height="119" HorizontalAlignment="Left" Margin="12,39,0,0" VerticalAlignment="Top" Width="736"
ItemsSource="{Binding PagedListOfPersonEmail, Mode=TwoWay}"
ColumnHeaderStyle="{StaticResource ColBinding}"
SelectedItem="{Binding SelectedPersonEmail, Mode=TwoWay}"
IsReadOnly="{Binding PersonEmailDataContainerIsReadOnly, Mode=TwoWay}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True"
CanUserSort="True" Width="Auto" />
<sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True"
CanUserSort="True" Width="20*"
Binding="{Binding Email, Mode=TwoWay}"
Header="{Binding ConverterParameter=HdrEmail, Converter={StaticResource Localization}, Source={StaticResource Localization}}" />
<sdk:DataGridTextColumn CanUserReorder="True" CanUserResize="True"
CanUserSort="True" Width="20*"
Binding="{Binding WebSite, Mode=TwoWay}"
Header="{Binding ConverterParameter=HdrWebSite, Converter={StaticResource Localization}, Source={StaticResource Localization}}" />
</sdk:DataGrid.Columns>
<!-- more columns -->
</sdk:DataGrid>
I solved it by removing the first column, which is just a blank column. It displays no data, it has no bindings, it doesn't even have a header to display. Any ideas why this was causing the error?
If you have a DataGrid that is bound to an ItemsSource then you cannot have a sdk:DataGridTextColumn that does not have a binding. You can use the sdk:DataGridTemplateColumn instead. This column type does not require a binding.

Share context menu in WP7 xaml

I want to add a contextmenu to items in a listbox. Typically the answer is to add the contextmenu to the root of the item template. However, I am using a template selector, so there are multiple templates in use, depending on the data of each item in the listbox. This means I need to add the same contextmenu definition to each template, which is not very appealing.
One solution is to wrap the datatemplate in a ContentControl, which would give me a single place for the context menu definition. However, I believe this would add layout overhead that isn't necessary.
Another solution I tried is adding the ContextMenu to the resource dictionary, but I believe this ends up sharing the same object instance across all the uses, and due to the way ContextMenu is implemented, this also does not work.
A third solution is using the Loaded event to call a function which populates the context menu appropriately. However, this ends up moving a lot of code that ought to be in the XAML into code, and looks quite ugly. If there's some way of defining the context menu in xaml, and then just referencing that from code, I would find it appealing, but I don't quite see how to do that.
What is the right way to share the same ContextMenu across the templates in a template selector?
This is the ContentControl method, which works, but ends up adding two content controls to each item:
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Loaded="ContextMenu_Loaded">
<toolkit:MenuItem Header="Delete"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<ContentControl ContentTemplate="{StaticResource MyTemplate}" Content="{Binding}"/>
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
How about adding the ContextMenu to the TemplateSelector?
<ListBox ItemsSource="{Binding}">
<ListBox.Resources>
<DataTemplate x:Key="MyTemplate">
<StackPanel>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<local:CustomTemplateSelector Content="{Binding}">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Delete"
Click="MenuItem_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<local:CustomTemplateSelector.TemplateOne>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Blue" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateOne>
<local:CustomTemplateSelector.TemplateTwo>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Red" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateTwo>
<local:CustomTemplateSelector.TemplateThree>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Yellow" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateThree>
</local:CustomTemplateSelector>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I ran this and it worked for me - give it a try and let me know if this was the effect you were looking for or not.