WinUI ListView ObservableColellection binding not working - c#

I'm learning the new WinUI platform together with XAML and GUI programming in C# and I'm not sure if I correctly understand how the bindings and updates work, but I can't get the following code (minimal working example) to work:
MainPage.xaml
<Page
x:Class="uitest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<ListView ItemsSource="{x:Bind Items, Mode=OneWay}"></ListView>
<Button Content="Add" Click="Button_OnClick"></Button>
</StackPanel>
</Page>
MainPage.xaml.cs
using System.Collections.ObjectModel;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace uitest
{
public sealed partial class MainPage : Page
{
public ObservableCollection<string> Items = new ObservableCollection<string>();
public MainPage()
{
this.InitializeComponent();
Items.Add("A");
Items.Add("B");
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
Items.Add("Next");
}
}
}
When I start the application, I see a list with two items but when I click the button nothing happens. I wanted to use the Live Visual Tree for debugging but it's not working for some reason.

I opened an issue on the official WinUI repository for this and apparently it's a compatibility fault in the latest WinUI 3 preview. I should also note this does not work only on the UWP platform but it works on the Desktop (Win32).

Related

Using Sample Data saved as XAML, at Design Time in UWP

I am reading this article and trying to use a sample data for ListView to display the data at the design time.
However, I cannot make it, and am seeing an error saying that it cannot build the DataContext in the ListView at the highlighted part below.
d:DataContext="{d:DesignData SampleData.xaml}"
Visual Studio 2019 16.9.1
The files are as below. These have been saved in one folder in flat.
Could you help me to know the appropriate way of such using of sample data?
MainPage.xaml:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
d:DesignWidth="459" d:DesignHeight="262">
<Grid>
<ListView d:DataContext="{d:DesignData SampleData.xaml}"
ItemsSource="{Binding Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="-- " />
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Age}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
SampleData.xaml (marked as DesignData for the build action):
<sample:PersonCollection
xmlns:sample="using:App1">
<sample:Person Name="John Doe" Age="20" />
<sample:Person Name="Jane Doe" Age="30" />
</sample:PersonCollection>
Person.cs:
namespace App1 {
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public Person() {
}
}
}
PersonCollection.cs:
using System.Collections.ObjectModel;
namespace App1{
public class PersonCollection : ObservableCollection<Person> {
public PersonCollection(): base(){
}
}
}
Using Sample Data saved as XAML, at Design Time in UWP
I'm afraid you can't use Xaml design data for UWP app, derive from this document,
One good option is the Create Sample Data from Class feature in Blend for Visual Studio. You can find that command on one of the buttons at the top of the Data panel. Unfortunately,
The Data panel in Blend is supported only for projects that target .NET Framework. It's not supported for UWP projects or projects that target .NET Core.

WPF WebView doesn't show

I'm learning WPF WebView control, I have the below MainWindow.xaml file:
<Window x:Class="MyWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid x:Name="Grid1" Grid.Row="1" Grid.Column="1">
<WPF:WebView x:Name="webView1"
Grid.Row="0"
Grid.Column="0"
Loaded="WebView_Loaded" />
</Grid>
</Window>
and the below corresponding MainWindow.xaml.cs file:
namespace MyWPF
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
webView1.Navigate(new Uri("https://www.google.com"));
}
private void WebView_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
But I don't get any expecting popup window. If I remove
webView1.Navigate(new Uri("https://www.google.com"));
I can get a blank popup window. What is wrong with my code and how to solve it?
UPDATE1
I added Window_Loaded event handler and move the below two in it, now I can see a blank popup window but without any content as well as message box.
Uri uri = new Uri("https://www.google.com");
WebView1.Navigate(uri);
The whole updated code-behind:
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
Uri uri = new Uri("https://www.google.com");
WebView1.Navigate(uri);
}
}
}
UPDATE2
I added one HyperLink and one Button into xaml file, the below is the updated xaml file:
<Window x:Class="MyWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" AllowsTransparency="False" >
<Grid x:Name="Grid1" Visibility="Visible" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="71*"/>
</Grid.ColumnDefinitions>
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50">
</WPF:WebView>
<Button Name="BTN1" Click="BTN1_Click" Margin="285,380,285,10" Grid.Column="1" >Click Me</Button>
<TextBlock Margin="0,0,747,390" Grid.ColumnSpan="2">
<Hyperlink
NavigateUri="http://www.google.com">
Google
</Hyperlink>
</TextBlock>
</Grid>
</Window>
and adding Button click event handler into the code-behind with webview initialization inside it:
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
//Uri uri = ;
WebView1.Navigate(new Uri("https://www.google.com"));
}
private void BTN1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
WebView1.Navigate(new Uri("https://www.google.com"));
}
}
}
Nothing happens after clicking the HyperLink. I see popup Messagebox after clicking button but still google doesn't show up.
UPDATE3
I followed the link:
https://learn.microsoft.com/en-us/windows/communitytoolkit/controls/wpf-winforms/webview#high-dpi
I set Source property Source="http://www.google.com" inside the xaml file, see the below code:
<Window x:Class="MyWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyWPF"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" AllowsTransparency="False" >
<Grid x:Name="Grid1" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="71*"/>
</Grid.ColumnDefinitions>
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50" Source="http://www.google.com" >
</WPF:WebView>
<Button Name="BTN1" Click="BTN1_Click" Margin="285,380,285,10" Grid.Column="1" >Click Me</Button>
<TextBlock Margin="0,0,747,390" Grid.ColumnSpan="2">
<Hyperlink
NavigateUri="http://www.google.com">
Google
</Hyperlink>
</TextBlock>
</Grid>
</Window>
But still not working.
UPDATE4
I added((ISupportInitialize)webView).BeginInit() and ((ISupportInitialize)webView).EndInit() into the button click event handler, see the below:
using Microsoft.Toolkit.Wpf.UI.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace MyWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
}
private void BTN1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Loaded");
((ISupportInitialize)WebView1).BeginInit();
((ISupportInitialize)WebView1).EndInit();
WebView1.Navigate(new Uri("https://localhost:3000"));
Console.ReadLine();
}
}
}
But get the below error message at this line:
((ISupportInitialize)WebView1).BeginInit();
:
$exception {"Could not find any resources appropriate for the specified culture or the neutral culture. Make sure
\"Microsoft.Toolkit.Win32.UI.Controls.DesignerUI.resources\" was
correctly embedded or linked into assembly
\"Microsoft.Toolkit.Wpf.UI.Controls.WebView\" at compile time, or that
all the satellite assemblies required are loadable and fully
signed."} System.Resources.MissingManifestResourceException
Then I went back and added more properties based on this link:
https://github.com/rjmurillo/webview-samples/blob/master/Toolkit/dotnet/Microsoft.Toolkit.Win32.Samples.WPF.WebView/MainWindow.xaml
<WPF:WebView x:Name="WebView1" Visibility="Visible" Grid.Column="1" Margin="50,50,50,50" Source="http://www.google.com" IsIndexedDBEnabled="True"
IsJavaScriptEnabled="True"
IsPrivateNetworkClientServerCapabilityEnabled="True"
IsScriptNotifyAllowed="True" >
</WPF:WebView>
But still WebView not working.
I was having the same issue upgrading from the first preview Toolkit, and it was all because the Navigate function causing to start window hidden.
Change from:
WebView1.Navigate(new Uri("https://localhost:3000"));
To:
WebView1.Source = new Uri("https://localhost:3000");
I was also having this issue and even using the myWebBrowser.Source = new Uri("https://www.google.com"); it was not showing the page.
I added the following to the code and now it loads fine.
myWebBrowser.BringIntoView();
I am using this with WPF and displaying it in a popup window, I'm not sure if that has anything to do with the issue I was having or not.
Did you run your program as an administrator (with elevated privileges), either directly or through Visual Studio?
According to this discussion this is not possible, the Win32 WebView does not support running under an elevated token.
If you check your Windows event log, you should also find an application error like the one mentioned in the discussion.
I also tried to use WebView WPF, but it can not show when I use webview.Source = url as accepted answer.
Finally, I changed to use CefSharp.Wpf library following this link https://www.technical-recipes.com/2016/using-the-cefsharp-chromium-web-browser-in-wpf-xaml/
And it worked perfectly at my site, i shared for whom concerned.
Create a new WPF project
Obtain the CefSharp packages using NuGet
Select Tool > NuGet Package manager > Package Manager Console.
Use the PM> install-package CefSharp.Wpf
Use in WPF as
<Window x:Class="CefSharpBrowser.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
Title="MainWindow"
Height="350" Width="525">
<Grid>
<wpf:ChromiumWebBrowser
x:Name="Browser"
Address="http://www.myaddress.com" />
</Grid>
</Window>

how to show auth0 client loginasync in webview

I am trying to build an app with login page that uses auth0, now when I call LoginAsync the sdk will popup the login page in a different frame, I want to show the login page in a webview that is defined in xaml.
I want to show login page that popup in this [ in a webview defined in this is xaml:
<Page
x:Class="Auth0App.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Auth0App"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Margin="10,0">
<StackPanel>
<TextBlock Style="{ThemeResource SubheaderTextBlockStyle}">Log in using widget</TextBlock>
<Grid HorizontalAlignment="Center" Margin="0,10">
<Button Content="Login" x:Name="LoginButton" Click="LoginButton_OnClick"/>
</Grid>
</StackPanel>
<StackPanel>
<WebView Name="loginWebView"/>
</StackPanel>
</StackPanel>
</Page>
and the code behind is:
using Auth0.SDK;
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Auth0App
{
public sealed partial class MainPage : Page
{
private Auth0Client auth0Client;
public MainPage()
{
this.InitializeComponent();
auth0Client = new Auth0Client("mydomain", "**************************");
}
private async void LoginButton_OnClick(object sender, RoutedEventArgs e)
{
try
{
var user = await auth0Client.LoginAsync();
}
catch (Exception ex)
{
}
}
}
}
How would I wire auth0 client with my webview?
I would start by looking at the Auth0 quickstart for this kind of project. I think you're about halfway there, and the quickstart would get you the rest of the way.
Feel free to reach out if there's anything missing or you need further assistance!
--Kassandra Perch, Developer Evangelist

See WPF list view adding items 1 by one instead of all at once

I have spent ages experimenting and googling but have thus far come up with no answer
I have a WPF list view that is using a WrapPanel as its items container.
For various reasons I dont want to virtualise the wrap panel.
Is it possible to show the items being added one by as they are completed in the value converter? so that the user is not looking at a blank screen while the items are loading?
This is a very common scenario, so I'm surprised that you didn't find anything during your search. Perhaps if you would have used the word 'Asynchronous', you would have had more luck. Either way, the answer is to use the Dispatcher class.
In short, you can add tasks to the message queue of the UI Dispatcher object, so that it can run them asynchronously. There are many examples of this online, but here is one that I found in the Load the Items in a ListBox Asynchronously page of the Java2s website:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" Height="200" Width="300"
Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="ListItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListBox x:Name="listBox" ItemTemplate= "{StaticResource ListItemTemplate}"/>
</StackPanel>
</Window>
//File:Window.xaml.cs
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
public partial class Window1 : Window
{
private ObservableCollection<string> numberDescriptions;
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
numberDescriptions = new ObservableCollection<string>();
listBox.ItemsSource = numberDescriptions;
this.Dispatcher.BeginInvoke(DispatcherPriority.Background,new LoadNumberDelegate(LoadNumber), 1);
}
private delegate void LoadNumberDelegate(int number);
private void LoadNumber(int number)
{
numberDescriptions.Add("Number " + number.ToString());
this.Dispatcher.BeginInvoke(DispatcherPriority.Background,new LoadNumberDelegate(LoadNumber), ++number);
}
}
}

View is not being resolved with Toolbar ItemsSource

It doesn't seem like the Caliburn Micro framework is retrieving my SinglePaintToolbarView when it is binded as a list of buttons in the toolbar of the ShellView. I would like the buttons to just display their text content when they are added to the toolbar. But, instead I'm getting this:
There doesn't appear to be any clickable buttons in the toolbar. I know my plugins are being loaded successfully, because I was able to bind one of the plugins in the list as a ContentControl and the view appeared. It just doesn't seem to work when I try to bind a list of the plugins in a toolbar.
Here is what I have:
ShellView.xaml
<UserControl x:Class="Starbolt.Views.ShellView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ToolBarTray>
<ToolBar ItemsSource="{Binding Path=ToolbarPlugins}"/>
</ToolBarTray>
</Grid>
</UserControl>
ShellViewModel.cs
[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
[ImportMany(typeof(IToolbarPlugin))]
private IEnumerable<IToolbarPlugin> _toolbarPlugins = null;
public IEnumerable<IToolbarPlugin> ToolbarPlugins { get { return _toolbarPlugins; } }
}
SinglePaintToolbarView.xaml
<UserControl x:Class="Starbolt.Plugin.SinglePaintTool.Views.SinglePaintToolView"
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"
mc:Ignorable="d"
d:DesignHeight="128" d:DesignWidth="32">
<Button Name="btnSinglePaintTool" Content="Single Paint Tool" Width="128" Height="32"/>
</UserControl>
SinglePaintToolViewModel.cs
[Export(typeof(IToolbarPlugin))]
public class SinglePaintToolViewModel : IToolbarPlugin
{
}
Basically, your design seems to be working. If you replace
<ToolBarTray>
<ToolBar x:Name="ToolbarPlugins"/>
</ToolBarTray>
(note that you do not need to bind the ItemsSource explicitly, you can just as well use the Caliburn Micro property name conventions) with the following:
<ListBox x:Name="ToolbarPlugins"/>
the SinglePaintToolView button is displayed as intended.
I suspect that the problem is with the ToolBar ControlTemplate, which most certainly restricts the toolbar items layout more than what for example a ListBox ControlTemplate does.
So my guess is that if you really want to use the ToolBar control to display your IToolbarPlugin views, you will probably have to design a dedicated ToolBar control template in your project.
Alternatively, you could implement a toolbar replacement using e.g. ListBox. This could be a start:
<ListBox x:Name="ToolbarPlugins">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>

Categories