I have a UWP application based on the Template10 hamburger template. I added the following modal dialog.
<Controls:ModalDialog x:Name="LoginModal"
CanBackButtonDismiss="False"
DisableBackButtonWhenModal="True">
<Controls:ModalDialog.ModalContent>
<views:LoginView x:Name="loginPart"
HorizontalAlignment="Center"
VerticalAlignment="Center"
HideRequested="LoginHide"
LoggedIn="LoginLoggedIn" />
</Controls:ModalDialog.ModalContent>
</Controls:ModalDialog>
My login view is declared like this
[Export]
public sealed partial class LoginView : Page, IView
{
....
}
For some reason the xaml extract above gives me a design time error saying "Cannot create an abstract class." The project builds and runs ok but the xaml designer won't work.
Anyone know what I'm doing wrong here?
LoginView would need to be a UserControl not a Page. The other properties would be added to that codebehind of that usercontrol to allow for interaction with the ModalDialog
From the Samples folder...
https://github.com/Windows-XAML/Template10/blob/master/Samples/Search/Controls/LoginPart.xaml.cs
if this doesn't work then I would suspect the MEF [Export]
Related
Many questions have been asked about using a XAML element from the View in the ViewModel. But what about defining a XAML element in the ViewModel and using that in the XAML markup of the View? So that the ViewModel knows about the element from the get-go(and owns the element).
I was trying to do this thinking it would be more MVVM-compliant--the ViewModel doesn't have to know about the entire View in order to use this component. But I recognize it's still not really in the spirit of MVVM to define a XAML element in the ViewModel. But at this point, I just want to know if this technique is possible.
I know I can define a property in the ViewModel, and then bind that to a property of a XAML element defined in the View. E.g. defining a string in the ViewModel and binding that to the Text property of a TextBlock XAML element. But is it possible to simply define the XAML element itself in the ViewModel and use that in the XAML markup of the View?
Example code. I'm using C++/WinRT with WinUI 3:
MainWindowViewModel.idl
namespace MyApp
{
runtimeclass FooViewModel
{
MainWindowViewModel();
Int32 IntProperty; // I can bind this to a XAML element's property
Microsoft.UI.Xaml.Controls.Frame Frame; // Can I use this in the View?
}
}
MainWindow.idl (View)
import "ViewModel/MainWindowViewModel.idl";
namespace MyApp
{
runtimeclass MainWindow : Micorosoft.UI.Xaml.Window
{
MainWindow();
MainWindowViewModel MainWindowViewModel{ get; };
}
}
MainWindow.xaml (View's XAML)
<Window
x:Class="MyApp.MainWindow"
//...
>
<StackPanel>
// I can bind to a property of MainWindowViewModel as such:
<Slider Minimum="0" Maximum="{x:Bind MainWindowViewModel.IntProperty}" />
// Is there a way to use the Frame defined in MainWindowViewModel here, or can you only create a new Frame instance?
<Frame/>
</StackPanel
</Window>
Is it possible to simply define the XAML element itself in the
ViewModel and use that in the XAML markup of the View?
Yes, It will be work.
I tested it in WinUI3 C# and the code works fine.
I've got the following problem: In my main xaml page I've got a button which navigates to an other page which is called settings and which also includes settings for the app. I jump to the page with the following method:
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Settings::typeid));
As you can understand I want the UI-Elements (Comboboxes/Sliders) to save theier attributes for the next time. Not even for the next launch of the app, just for the next jump on the settings page. If I go back from settings to main page and back to settings again, the values of the comboboxes and slider are reseted. I need them to be saved for my program's logic.
In my c++-desktop app I'm using registry entrys in order to save it, but this is not quite possible in uwp and it's not the easiest solution. In Java I would use a global static variable which saves the values and which is bind to UI-elements. How can I implement this in UWP ?
You can achieve that with the Page.NavigationCacheMode Property. With that property you are able to store the state of the page in the cache of the application.
You can either use it in the xaml-tag of the page, or set in the constructor in the code-behind of the page. You can find the possible values of the properties here.
Example-XAML:
<Page
x:Class="Foo.Namespace.SettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Foo.Namespace"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
NavigationCacheMode="Enabled">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
</Grid>
</Page>
Example CS:
public sealed partial class SettingsPage : Page
{
public SettingsPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Enabled;
}
}
How to Unit Test the WPF View Files like Sample.xaml and sample.xaml.cs files in mvvm pattern
In WPF you don't need to unit test the xaml. Xaml are just UI that are bound to the view model. What you really need to test is the view model after all, the state of the application should be in the view model not in the xaml.
Let's say for example you want to test if a button is visible after a certain logic. What you need to do is to create a property in the viewmodel (i.e. IsButtonShown) which is a boolean and bind it to the visibility of the button that has a boolean to visibility converter.
<Button Content="Click Me!" Visibility="{Binding IsButtonShown, Converter={StaticResource booleanToVisibility}}" />
Through binding you can now see the state of every property of the UI from the viewmodel so that you don't need to create a unit test for the xaml.
Now in your unit test, you can do something like:
[TestMethod]
public void TestMethod1()
{
viewModel.InsideThisMethodWeSetIsButtonShownToFalse();
Assert.IsTrue(!viewModel.IsButtonShown);
}
In my case in need change this
<DrawinSurfaceBackgroundGridgx:Name="DrawingSurfaceBackground"Loaded="DrawingSurfaceBackground_Loaded">
</DrawingSurfaceBackgroundGrid>
to this
<Grid>
<phone:WebBrowser Name="MiniBrowser" Visibility="Collapsed"/>
<!--LayoutRoot is the root grid where all page content is placed-->
<DrawingSurfaceBackgroundGridx:Name="DrawingSurfaceBackground"Loaded=
"DrawingSurfaceBackground_Loaded">
</DrawingSurfaceBackgroundGrid>
</Grid>
When unity3d build default project there is a default MainPage. I need too add a webbrowser component in this mainpage from my unity3d plugin. And then i need to call browser navigate and subscribe to some browser events like loadCompleted Is it possible? Plese give me an example
You can get add/remove items programatically. If you can access the MainPage class you can get to it's content, which is the grid, and to its children which is an UIElementCollection which implements IList.
IList has an insert method which allows you to insert an element at a specified index, in your case 0, here a full example:
MainPage mainPage = new MainPage();
var miniBrowser = new WebBrowser
{
Visibility = Visibility.Collapsed;
};
mainPage.Content.Children.Insert(0, miniBrowser);
I didn't add a name to the WebBrowser class since because it is being added programatically it really makes no difference (the Name property is used at design time (xaml is parsed at design time and at runtime[in the InitializeComponent method]) to generate a property in a partial class (MainPage.i.g.cs/MainPage.g.cs)).
The way you get hold of MainPage is usually from Application.Current.Content (Application.Current will contain a Frame whose Content is MainPage).
I'm developing a WP7 application, and I'm generating a listbox with a few items. I was wondering if there is a way to preview how the layout would look. So far, since the elements don't exist, I can't "preview" them.
Is there some way to feed some dummy data or other methods that would help in previewing xaml layouts ?
First - it helps if you use MVVM, or at least ItemsSource binding + ItemTemplate to display your items. Once you are there - Expression Blend has some great tools for sample data.
You go to Data tab, click Create Sample Data/New Sample Data. It will create a sample data as XAML and bind your page to it like that:
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
Then you can add new properties, model collections with different data types and it will automatically generate some data you can use in your XAML.
You should provide a designer data.
There are several ways to do it.
One of the simplest, is to provide a DataContext in your XAML declaration for designer to use when rendering your page display.
In Xaml page declaration:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance local:DesignerSampleData, IsDesignTimeCreatable=True}"
The sample data class should have the data that your visual elements bind to:
public class DesignerSampleData: INotifyPropertyChanged
{
public DesignerSampleData()
{
_sampleData = "My test string that will display in VS designer for preview";
}
private String _sampleData;
public String SampleData
{
get { return _sampleData; }
set
{
if (value != _sampleData)
{
_sampleData = value;
NotifyPropertyChanged("SampleData");
}
}
}
In xaml bind to SampleData:
<TextBlock Text="{Binding SampleData}" />