C# MVVM Prism questions - c#

I try to understand C# prism framework, and make a little project. I meet some problem with misunderstanding Prism concept. I will explain what i want to do, what i try, my code:
I want to make a simple application like a test with 5 random question. You select difficult of test after you press start. On the same window your page is change with first question. Select right answer , next and you go on the second page with second question. From the second question you have 2 buttons(prev and next) , next next next, finish and you have a message like "you got x/5 points".
I have a similar aplication but the framework use is Caliburn.
First Application
I want to put all questions in xaml file now.
What i try:
I follow documentation, youtube tutorials for 2 days.
I create 2 folders: View and ViewModel. Create MainPage.xaml like a window in View and in ViewModel i create MainPageViewModel, in file MainPage.cs i create one instance like:
MainPageViewModel main = new MainPageViewModel();
After this i create a button i test the button and work.
Now I want to create a Page to connect with MainPageViewModel window. In the page i want to create another button and i want to check if is work. But this is the step how can't create.
After follow few tutorials, i can't make this. Not work to connect on the xaml file MainPageViewModel.
MainPage:
<Window x:Class="Aplicatie2._0.View.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"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:Aplicatie2._0.View"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="{Binding Title}" Height="450" Width="800">
<Window.DataContext>
</Window.DataContext>
<Grid>
</Grid>
</Window>
Error MC3063: Property 'DataContext' does not have a value. Line 14 Position 30.
MainPageViewModel:
using Prism.Mvvm;
using Prism.Navigation;
using Prism.Commands;
namespace Aplicatie2._0.ViewModel
{
class MainPageViewModel : BindableBase
{
private string _Title = "Test";
public string Title
{
get
{
return _Title;
}
set
{
SetProperty(ref _Title, value);
}
}
}
}
App.xaml:
<prism:PrismApplication x:Class="Aplicatie2._0.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:Aplicatie2._0">
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
App.xaml.cs:
using Prism.Modularity;
using Prism.Ioc;
using System.Windows;
using System.ComponentModel;
using Prism.Unity;
using Aplicatie2._0.View;
namespace Aplicatie2._0
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainPage>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainPage>("MainPage");
}
}
}
1)How can i create multiple page and how can connect with main window?(If i call page1 i want to be clear, to create button and Radiobutton on the page)
2)How can i connect ViewModel file with View file on xaml, without create instance?
3)How can i create one question in xaml like:
Question: This is first question
[] Answer1
[] Answer2
[] Answer3
If you can to give me an example it's perfect, but make it simple.

Related

Cannot access inherited property in XAML codebehind

I am making a Property Sheet shell extension using SharpShell. Initially I tried using WinForms for the Property page, but the limitations of controls like PropertyGrid, ListView etc. made me choose WPF. So I created a WPF User Control Library project and added SharpShell to my project from Nuget.
I made a new Page, I guess, I am new to VS & WPF, but it shows "Build Action" as "Page". Now my code-behind looks like this:
using SharpShell.SharpPropertySheet;
using SharpShell.Attributes;
using System.Runtime.InteropServices;
namespace FLPShellExtension
{
[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".flp")]
public partial class FLPPropertyPage : SharpPropertyPage
{
public FLPPropertyPage()
{
InitializeComponent();
PageTitle = "Project Info";
}
}
}
XAML looks like this:
<UserControl x:Class="FLPShellExtension.FLPPropertyPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:wc="clr-namespace:FLPShellExtension;assembly=SharpShell"
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="450" d:DesignWidth="800">
<Grid></Grid>
</UserControl>
Here, VS complains of two things:
CS0103: The name 'PageTitle' does not exist in the current context
XAML1103: Namespace 'wc' is unnecessary
The PageTitle = "Project Info" worked in WinForms. It is a public string defined in SharpPropertyPage. I found about this wc namespace from a similar question asked elsewhere.

"Kproj.Forms.frmSwitch" cannot be the root of a XAML file because it was defined using XAML

I am aware that there are other questions posted that appear to be the same issue but none of them fix my issue.
I'm new to WPF I'm trying to convert a program from WinForms to WPF. I have a main window, "Kproj.Forms.frmLogin", that inherits a base class, "Kproj.Forms.frmSwitch", that inherits the System.Windows.Window class. WhenI got the above issue, my initial XAML code was:
<Control:frmSwitch x:Class="Kproj.Forms.frmLogin"
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:Control="clr-namespace:Kproj.Forms"
mc:Ignorable="d"
Title="LOG IN" Height="309" Width="678">
<Grid Height="271" Width="662">
... Content
</Grid>
</Control:frmSwitch>
with these in the code-behinds:
namespace Kproj.Forms
{
public partial class frmLogin : frmSwitch
{
}
}
namespace Kproj.Forms
{
public partial class frmSwitch : Window
{
}
}
Upon further research, I found out that I needed to make frmSwitch into a base class with no XAML. Thus, I created frmSwitch2 in just general Class form that looks like this:
namespace Kproj.Forms
{
public class frmSwitch2 : Window
{
}
}
I then adjusted the main window XAML accordingly:
<Control:frmSwitch2 x:Class="Kproj.Forms.frmLogin"
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:Control="clr-namespace:Kproj.Forms"
mc:Ignorable="d"
Title="LOG IN" Height="309" Width="678">
<Grid Height="271" Width="662">
... Content
</Grid>
</Control:frmSwitch2>
and the main window code-behind to:
namespace Kproj.Forms
{
public partial class frmLogin : frmSwitch
{
}
}
Now, I lost the original error message, but I gained a message that states
"The name 'frmSwitch2' does not exist in the namespace 'clr-namespace:FITS.Forms'."
even though it suggests "frmSwitch2" when I type "Control:" in the main window XAML, so it knows it does exist in the namespace. Any suggestions?
Disclaimer: I tried researching it as best as possible but all the posts I found on StackOverflow were this issue but all were fixed by converting from XAML\cs partial classes to solo code-behind full XAML-less class.
After looking into what the inheritance actually wanted, I learned that the only purpose of the inheritance was for variables so I was able to make it work but just converting them to static global variables and accessing them directly. I ended up not needing the inheritance after all.
If anyone else, that ends up knowing more MVVM, does come across a fix for this issue, it would be nice to know it. Even though I no longer need it, it would be good learning.

Get Geolocation Bing Map W10 Universal App When Right Clicked/Long Press

I'm developing a universal map for windows 10 (VS 2015) and I have a map control. I want to capture a long press / right click event and determine the geolocation (lat/lng) where the user presses. I've tried capturing the right click event, but it never fires whether I use the mouse or a long press on the map:
<Page
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"
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
x:Class="App1.MainPage"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Maps:MapControl
x:Name="Map"
MapServiceToken="<MY_TOKEN>"
ZoomInteractionMode="GestureAndControl"
LandmarksVisible="True"
IsRightTapEnabled="true"
RightTapped="Map_RightTapped"
/>
</Grid>
</Page>
C#:
using System.Diagnostics;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
namespace App1
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Map_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
Debug.WriteLine("Here");
}
}
}
Evidently I'm missing something. Thanx,
Update: I have a work around of sorts. I can capture the data I need from a long press using the MapHolding event, but there does not seem to be support for a right click. The class documentation indicates there is a MapRightTapped event (https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.maps.mapcontrol.maprighttapped.aspx) but it isn't available either in in the XAML editor or in the .cs file using intellisense. Note that the event is MapHolding, not Holding (e.g., use myMap.MapHolding += EventHandlerMethod, not myMap.Holding += EventHandlerMethod).
I believe the right click event is not currently supported on the map however, this is in the next Windows update later this month.

In WPF, access a control that is instantiated in a XAML file from a separate Class?

We have a class in our WPF project that we want to access a control that is put into a XAML file. I have put my code below and file structure to help with my question.
Folder Structure:
Navigation Directors\ FullKioskDirector.cs
MasterTemplates \ SellAllKioskMaster.xaml
Views \ Pages \ PageTemplates \ PageAttractScreen.xaml
We want 'FullKioskDirector.cs' to access the visibility of 'PageAttractScreen.xaml'. The 'SellAllKioskMaster.xaml' is referencing the 'PageAttractScreen.xaml' in its XAML.
Here is our code below.
SellAllKioskMaster.xaml
<UserControl
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:UserControls="clr-namespace:Kiosk.Views.Pages.UserControls" xmlns:PageTemplates="clr-namespace:Kiosk.Views.Pages.PageTemplates" x:Class="Kiosk.MasterTemplates.MyContainer"
mc:Ignorable="d"
d:DesignHeight="1049" d:DesignWidth="1912" Background="White">
<Grid>
<!--I need to access the visibility of these elements from the 'FullKioskDirector.cs'-->
<PageTemplates:PageAttractScreen x:Name="pageAttract" Margin="0,100"/>
<PageTemplates:PageWelcomeScreen x:Name="pageWelcome" Margin="0,100"/>
<PageTemplates:PageProductsScreen x:Name="pageProducts" Margin="0,100"/>
</Grid>
</UserControl>
FullKioskDirector.cs
using System;
using System.Windows;
using System.Windows.Controls;
using Kiosk.Common.Common.Contracts;
using Kiosk.Views.Pages.UserControls;
namespace Kiosk.Directors
{
public class FullKioskDirector : IPageNavigation
{
public FullKioskDirector()
{
/*
Want to control visibility of my controls that are placed and
x:Named in the SellAllKioskMaster.xaml
*/
}
How can I accomplish this?
It's better if you do it in an MVVM approach, rather than doing everything from code behind.
Nevertheless, wherever you are creating FullKioskDirector, just pass in pageAttract to the constructor.
Assuming you create the FullKioskDirector at UserControl's constructor
public UserControl()
{
var fullKioskDirector = new FullKioskDirector(pageAttract);
}
Then you can use it like this
public FullKioskDirector(PageAttractScreen pageAttract)
{
pageAttract.Visibility = Visibility.Collapsed;
}
I would use a Publish / Subscribe pattern.
Example: MessageBus / EventAggregator
This is my tool of choice when dealing with dependency challenges.
Essentially, you just post a message for subscribers to react to.
In this case your subscriber will then post a response in the form of a control.
You can leverage Bizmonger.Patterns to get the MessageBus.
https://msdn.microsoft.com/en-us/library/ff921122.aspx

Window Binding to UserControl ViewModel

I need help with binding a window to a user control view model. Here's my user control, nice and simple.
<UserControl x:Class="WindowBindTest.UserControlTest"
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"
xmlns:ViewModel="clr-namespace:WindowBindTest.UserControlViewModel"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<ViewModel:UserControlViewModel></ViewModel:UserControlViewModel>
</UserControl.DataContext>
<Grid>
</Grid>
</UserControl>
Here's my view model
namespace WindowBindTest
{
public class UserControlViewModel
{
public Window hostWindow { get; set; }|
public UserControlViewModel()
{
// I want to set the host window
// If something isn't defined then close the host window.
}
}
}
I could use a button to close the window but what if I didn't want to use a button. Is there a way to do that?
Could I pass in the parent window into the constructor?
You can do this in MVVM but you will need to use a service. In fact, this is where MVVM is weak (without using a framework such as Prism et al.). The following is a link to disore's DialogService class on CodeProject. it is awesome, but it will take time to get to grips with how it works.
The above library will enable you to close a View from a ViewModel.
I hope this helps.

Categories

Resources