Xamarin Page Renderer WinRT Desktop UserControl not rendered - c#

I've tried to adding a Xaml UserControl and/or UserPage in WIndows Desktop project added in Xamarin. None of Windows UI items (page or usercontrol and buttons) are displayed by page renderer. Can you please help where could I be making mistake.
CameraPageRenderer
[assembly: ExportRenderer(typeof(Shared.CameraPage), typeof(CameraPageRenderer))]
namespace MyApp.Windows
{
public class CameraPageRenderer : PageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
try
{
//1st test
this.Children.Add(new PhotoCaptureControl());
//[OR] 2nd Test
this.Children.Add(new PhotoCapturePage());
}
catch (Exception ex)
{
//Logger class
}
}
}
CameraPage
Invoked from Portable library page
public class CameraPage : ContentPage
{
public CameraPage(TaskCompletionSource<MediaFile> SelectionTask)
{
Content = new StackLayout
{
};
}
}
PhotoCaptureControl.xaml
.cs file has Initialize method.
<UserControl x:Class="MyApp.Windows.PhotoCaptureControl"
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:local="using:MyApp.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<StackPanel>
<TextBlock Text="Capture Photo text" />
<Button x:Name="BtnCapturePhoto"
HorizontalAlignment="Center"
Content="Capture Photo" />
</StackPanel>
</UserControl>
PhotoCapturePage.xaml .cs contains InitializeComponents() method
<Page x:Class="eWorker.Windows.PhotoCapturePage"
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:local="using:eWorker.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="BtnCapturePhoto"
Grid.Row="1"
HorizontalAlignment="Center"
Content="Capture Photo" />
</Grid>
</Page>

I found a partial solution to my problem. It will work in case of PhotoCapturePage but may not in case of UserControl PhotoCaptureControl.
I replaced following line of code
this.Children.Add(new PhotoCapturePage());
with -
this.SetNativeControl(new PhotoCapturePage());
This solution will not work if it is required to add one or more native UserControl.

Related

Load Region On Application Startup

I'm having some trouble gaining a working understanding of how Region Navigation works in Prism. I'm trying to create an MVVM based app that loads a main window, and displays a view generated by a login form. After the login form is submitted, I then want to navigate to a new UserControl. I'd like to know if this is also possible without using modules, however for the current implementation, it's modular.
With this current code, the menu bar with a button displays, but not the Login view.
Main Module
App.xaml.cs
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<LoginModule.ModuleLoginModule>();
}
MainWindow.xaml:
<Window x:Class="PrismMVVM.Views.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:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:local="clr-namespace:PrismMVVM"
mc:Ignorable="d"
Title="PrismMVVM" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<Button Content="Code is Poetry" HorizontalAlignment="Left" Width="Auto"/>
</DockPanel>
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion">
</ContentControl>
</Grid>
</Window>
MainWindowViewModel.cs
namespace PrismMVVM.ViewModels
{
class MainWindowViewModel : BindableBase
{
public IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
regionManager.RequestNavigate("LoginRegion", "Login");
}
}
}
Login Module
ModuleLoginModule.cs:
namespace LoginModule
{
public class ModuleLoginModule : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve<IRegionManager>();
regionManager.RegisterViewWithRegion("LoginRegion", typeof(Login));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<Login>();
}
}
}
Login.xaml:
<UserControl x:Class="LoginModule.Views.Login"
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"
xmlns:local="clr-namespace:LoginModule.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="White" prism:RegionManager.RegionName="LoginRegion">
<StackPanel Panel.ZIndex="1" Margin="150">
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center">Text</TextBox>
<PasswordBox HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Background="LightBlue" Content="Login" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<Rectangle Panel.ZIndex="0" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="LightGray" Height="300" Width="400" />
</Grid>
</UserControl>
I'd like to know if this is also possible without using modules
For sure it is. Modules are completely optional, you can do all the registrations from the bootstrapper / PrismApplication, if you like.
There's nothing wrong with something like this:
public class MyApplication : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<Login>();
}
}
internal class MainWindowViewModel
{
public MainWindowViewModel( IRegionManager regionManager )
{
regionManager.RequestNavigate( "ContentRegion", "Login" );
}
}

Can you get "Documenttitle from a user control?

I have created a user control with navigation buttons and textbox at top and a webview at bottom and the user control is called "browser". In my MainPage.xaml I have a Pivot and I load "browser like this ...
<PivotItem>
<local:Browser/>
</PivotItem>
and this all works! On my Pivot I have add and remove buttons to create new PivotItems with "browser" in them and that all works! What I cant figure out is how do I get the WebView.DocumetTitle from the WebView in "browser" control so I can put it in the PivotItem.Header when I create a new PivotItem?
You could define a dependency property and bind the PivotItem's header to it. Then you could register NavigationCompleted event for your WebView. When this event is fired, you could get current document page's title and assign this value to the dependency property. Then, the PivotItem's header will be updated.
I've made a simple code sample for your reference:
<UserControl
x:Class="App1.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="8*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox x:Name="txbUri" Grid.Row="0" Grid.Column="0"></TextBox>
<Button Content="Go" Grid.Column="1" Grid.Row="0" Click="Button_Click"></Button>
<WebView Grid.Row="1" x:Name="webview" Grid.ColumnSpan="2" NavigationCompleted="WebView_NavigationCompleted"></WebView>
</Grid>
public sealed partial class MyUserControl1 : UserControl
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(MyUserControl1), new PropertyMetadata("default"));
public MyUserControl1()
{
this.InitializeComponent();
}
private void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
this.Title = sender.DocumentTitle;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
Uri uri = new Uri(txbUri.Text.Trim());
webview.Navigate(uri);
}
catch
{
}
}
}
<Pivot>
<PivotItem Header="{Binding ElementName=uc,Path=Title}">
<local:MyUserControl1 x:Name="uc"></local:MyUserControl1>
</PivotItem>
</Pivot>

UserControl is not displayed

EDIT: It seems like that I needed to change the height of RowDefinition. Thanks goes to Alvaro. However:
how do I reference different elements inside my usercontrol (change their properties), when I want to change them in MainWindow.xaml and MainWindow.xaml.cs?
I have two XAML files in the same namespace.
MainWindow.xaml
List.xaml
When I try to add List.xaml usercontrol to my mainwindow xaml (that is insert xaml from another file), it does not show up.
I insert usercontrol that exists in Lemosystem namespace and inside View folder.
xmlns:lemoview="clr-namespace:Lemosystem.View"
I add usercontrol to my MainWindow.xaml:
<lemoview:List/>
Nothing shows up. Here is my List XAML (code is the default):
<UserControl x:Class="Lemosystem.View.List"
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>
<Label Content="What do you want to do today?" HorizontalAlignment="Left" Margin="10,96,-83,0" VerticalAlignment="Top" Height="44" Width="373" FontSize="24" FontWeight="Bold"/>
</Grid>
</UserControl>
I expect the label from my usercontrol to show up in MainWindow.xaml GUI, but it doesn't.
MainWindow.xaml
<Window x:Class="Lemosystem.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lemocontroller="clr-namespace:Lemosystem.Controller"
xmlns:lemoview="clr-namespace:Lemosystem.View"
Title="{Binding Path=SystemName}" Height="603" Width="827"
ResizeMode="NoResize" WindowStartupLocation="Manual"
>
<Grid Name="Window" Margin="0,0,2,0">
<Grid.RowDefinitions>
<RowDefinition Height="0*"/>
<RowDefinition/>
</Grid.RowDefinitions>
...
<lemoview:List/>
...
</Grid>
</Window>
And how do I reference different elements inside my usercontrol (change their properties), when I want to change them in MainWindow.xaml and MainWindow.xaml.cs?
So, I created a project with :
List.Xaml
<UserControl x:Class="WpfApplication1.List"
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>
<Label Content="{Binding TextToDisplay}"
HorizontalAlignment="Left"
Margin="10,96,-83,0"
VerticalAlignment="Top"
Height="44"
Width="373"
FontSize="24"
FontWeight="Bold" />
</Grid>
</UserControl>
ListViewModel.cs:
public class ListViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
private string textToDisplay;
public string TextToDisplay
{
get { return textToDisplay; }
set { textToDisplay = value; OnPropertyChanged("TextToDisplay"); }
}
public ListViewModel(string value)
{
TextToDisplay = value;
}
}
}
MainWindow.Xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:lemoview="clr-namespace:WpfApplication1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Content="Click Me" HorizontalAlignment="Center" Click="Button_OnClick"></Button>
<ListView Grid.Row="1" ItemsSource="{Binding MyList}"></ListView>
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
MyList=new ObservableCollection<ListViewModel>();
}
private ObservableCollection<ListViewModel> myList;
public ObservableCollection<ListViewModel> MyList
{
get { return myList; }
set { myList = value; }
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
MyList.Add(new ListViewModel("MyValue"));
}
}
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type wpfApplication1:ListViewModel}">
<wpfApplication1:List />
</DataTemplate>
</Application.Resources>
in App.xaml, I just defined the binding between List.xaml and ListViewModel.cs
the viewModel of MainWindow is itself.
after every Click on the button, a new ViewModel is created, added to the list with a defined value (you will need to modify this part, to set the value you want).
I hope it will help you ! it works for me.
How do you like to show something, if you put it il a row that has height ="0" ?
change it to :
<Window x:Class="Lemosystem.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lemocontroller="clr-namespace:Lemosystem.Controller"
xmlns:lemoview="clr-namespace:Lemosystem.View"
Title="{Binding Path=SystemName}" Height="603" Width="827"
ResizeMode="NoResize" WindowStartupLocation="Manual"
>
<Grid Name="Window" Margin="0,0,2,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<lemoview:List/>
</Grid>

A part of the webview content cannot be displayed when zoom factor > 5

I have a scrollviewer which contains a webview as content.When I zoom in(zoom factor > 5), a part of content can not be displayed.So Is this a bug?
[screen capture]
https://www.dropbox.com/s/rpqsor36cm6txbo/zoom_problem.xlsx
XAML File
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer x:Name="svMain" HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Enabled" VerticalScrollBarVisibility="Auto" VerticalScrollMode="Enabled" ZoomMode="Enabled" MinZoomFactor="0.7" MaxZoomFactor="10.0" Background="White" ViewChanged="svMain_ViewChanged" >
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<WebView Name="webview1" Source="http://www.yahoo.co.jp" Height="400" Width="400"
Grid.Column="1"></WebView>
<TextBlock Name="txtZoom" Margin="10,93,710,616" Grid.Column="1"/>
</Grid>
</ScrollViewer>
</Page>
CS File
namespace App1
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void svMain_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
txtZoom.Text = svMain.ZoomFactor.ToString();
}
}
}

Add a usercontrol to caliburm micro dynamically

I am using Caliburn Micro with WPF. I want to create an application with a menu on the left side, and a grid on the right side of the application. When clicking on a menu item, the grid on the right side, will change to another view. The another view will be in a separate file.
MainWindowView:
<UserControl x:Class="CMDemo.Views.MainWindowView"
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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="210*" />
</Grid.ColumnDefinitions>
<StackPanel Name="LeftMenu">
<Button Name="ChangeDisplay" Content="Click Me"></Button>
<TextBlock x:Name="MyString"></TextBlock>
</StackPanel>
<Grid Grid.Column="1" x:Name="MainGridContent" />
</Grid>
MainWindowViewModel:
public class MainWindowViewModel : PropertyChangedBase
{
private UserControl mainGridContent;
private string myString;
public UserControl MainGridContent
{
get { return this.mainGridContent; }
set
{
this.mainGridContent = value;
NotifyOfPropertyChange(() => this.MainGridContent);
}
}
public string MyString
{
get { return this.myString; }
set
{
this.myString = value;
NotifyOfPropertyChange(() => this.MyString);
}
}
public void ChangeDisplay()
{
this.MainGridContent = new ChangeDisplayView();
this.MyString = "Testing....";
}
}
The changeDisplayViewModel:
public class changeDisplayViewModel: PropertyChangedBase
{
}
The changeDisplayView:
<UserControl x:Class="CMDemo.Views.changeDisplayView"
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>
<TextBox content="Hello Caliburn Micro">
</Grid>
When I click the "Click Me" button the TextBlock "MyString" is updated and showing, but the usercontrol is not. What am I doing wrong?
Try changing MainGridContent to a changeDisplayViewModel rather than the view itself.

Categories

Resources