mainPage.xaml does not load into mainWindowMain frame in MainWindow.xaml - c#

I have two xaml:
MainWindow.xaml.
After running program i have only window with text:"mainPage.xaml". There is no menu or jpg that i had setup in mainPage.xaml
MainWindow.xaml code:
<Window x:Class="FK.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"
mc:Ignorable="d"
Title="A and I Version 0.1" Height="1080" Width="1920">
<Grid Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Frame x:Name="mainWindowMain"
Grid.Row="0">
</Frame>
</Grid>
MainWindow.xaml.cs code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 FK
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
mainWindowMain.Content = new Uri("mainPage.xaml", UriKind.Relative);
}
}
}
mainPage.xaml code:
<Window x:Class="FK.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:local="clr-namespace:FK"
mc:Ignorable="d"
Title="mainPage" Height="450" Width="800">
<Grid Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Menu
x:Name="mainWindowMainMenu"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="20"
Width="auto"
>
<MenuItem Header="Menu" Height="20" Width="50">
<MenuItem x:Name="menuOpcjaFinances"
Header="Finances"
InputGestureText="Ctrl+F"
Height="20"
Width="200"
>
</MenuItem>
<MenuItem x:Name="menuOpcjaInvoices"
Header="Invoces"
InputGestureText="Ctrl+I"
Height="20"
Width="200">
</MenuItem>
<MenuItem x:Name="menuOpcjaPomoc"
InputGestureText="Ctrl+H"
Header="Help"
Height="20"
Width="200"
>
</MenuItem>
<MenuItem x:Name="menuOpcjaWyjscie"
InputGestureText="Ctrl+Q"
Header="Exit"
Height="20"
Width="200"
></MenuItem>
</MenuItem>
</Menu>
<Image Grid.Row="1"
Source="/mainPicture_.jpg"
VerticalAlignment="Stretch"
HorizontalAlignment="Center"></Image>
</Grid>
</Window>
When I had in MainWindow two gridrows, in first gridrow i had menu from mainPage.xaml, and in second grid i had frame, after clicking one of menu, other xaml loads without any problems into the frame.
I tried to setup two gridrows in MainWindow,
i have tried to make public void with mainWindowMain.Content = new Uri("mainPage.xaml", UriKind.Relative); and insert the void in public MainWindow, but it does not help.
I have no errors while compiling the program, i do not know where to search the problem

First of all, your design is weird. You should have only one menu, in your MainWindow.xaml. Secondly - again - drop off frame control and use ContentControl instead. Frame control is heavy and It's not useful unless you want navigation and all It's features, like navigation history. Drop off Pages too, what you need is to go into the world of UserControls.
For your other "pages" - having each one It's own menu - you think this is nice design? Having top menu and then underlying view have another menu, really ?...I think your views (Pages in your case) should have TabControl, that would look and feel more normal to user. So your app would have top menu to navigate between views, and your views would have Tabs like "Invoices","Tax". That is only my opinion though.
However, you'll need to learn a lot more what WPF provides to you. I suggest you dig into MVVM pattern, WPF bindings, dependency injections, DataTemplates, Command bindings etc. Learning curve is steep, but you'll be glad once you'll figure It out.
Useful links for your answer:
navigation using ContentControl - MVVM article
SO question - check accepted answer
But, If you are a beginner, you can do It without MVVM pattern. Like you did, in code behind.
AND FINAL: If you still persist on your design, then instead of this line:
mainWindowMain.Content = new Uri("mainPage.xaml", UriKind.Relative);
create a click event of your MenuItem (in MainWindow) in code behind:
private void Menu_item_Click(object sender, RoutedEventArgs e)
{
mainWindowMain.Navigate(new mainPage());
}

Two major issues:
You are using the Frame wrong.
Window must always be the root element i.e. cannot be a child element.
1.) The value of Frame.Content will be directly rendered on the screen. That's why you only see the Uri.ToString() value "mainPage.xaml".
You must use the Frame.Source property instead. The Frame then loads the content that the URI points to by assigning it to the Content property: you don't want to display the string, but the content of the resource that the string references.
public MainWindow()
{
InitializeComponent();
mainWindowMain.Source = new Uri("mainPage.xaml", UriKind.Relative);
}
The recommended pattern is known as View Model First. See this short example: C# WPF Page Navigation.
2.) A Windowmust be the root element and can not be nested into another control i.e. it can't be a child.
To successfully display FK.mainPage as content of the Frame, you must turn it into a UserControl or some other container like Page:
mainPage.xaml
<Page x:Class="FK.mainPage">
...
</Page>

Related

MVVM how to pass object from main window to user control? [duplicate]

This question already has answers here:
What is DataContext for?
(4 answers)
Closed 4 months ago.
sorry about this question. I know MVVM exist for many years but each time I try to code something with it I face the same issue again and again ans I'm still looking for a real good tutorial about this.
Let's consider we have a main window (MainWindow.xaml) with its view model (MainViewModel.cs).
This window has a grid, in my grid I define 2 user controls. Whatever it is. One is on the left, one on the right. On my main window I have create, in MainViewModel.cs an engine:
internal class MainWindowViewModel
{
public MainWindowViewModel()
{
QCEngine qcEngine = new();
}
}
This engine is my unique model and contains a complex code that read data. Whatever. This engine has a public list of value. I want to display these values on my left and right panels in different ways. Again whatever. The display is not my issue.
My issue is how I pass this list or the entire engine reference to my panels? I'm really lost. I can do this in few seconds with any classic WinForms but I never figure out how to do in MVVM. I'm at this moment where I give up MVVM to do classic WinForms. This time I want to understand.
Can you help me?
My QC engine is a RFID reader. It already works fine as console application. All parameters are in a config file. the idea of the interface is to give more flexibility to the reader. Having a nice result screen, a setting screen, some interactions.
<Window x:Class="Beper.QCTable.Control.View.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:view="clr-namespace:Beper.QCTable.Control.View"
xmlns:viewmodel="clr-namespace:Beper.QCTable.Control.ViewModel"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800">
<Window.DataContext>
<viewmodel:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Menu -->
<Menu Grid.Row="0" FontSize="20">
<MenuItem Header="_Menu">
<MenuItem Header="_Advanced"/>
</MenuItem>
</Menu>
<!--Header-->
<StackPanel Grid.Row="1" Background="Orange">
<TextBlock FontSize="20">
Header
</TextBlock>
</StackPanel>
<!--Body-->
<Grid Grid.Row="2">
<view:TabPanel/>
</Grid>
<!--Status Bar-->
<StatusBar Grid.Row="3" FontSize="20">
<StatusBarItem>
Status
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
Focus on tab panel:
public class TabPanelViewModel
{
public ObservableCollection<TabItem> Tabs { get; set; } = new ObservableCollection<TabItem>();
public TabPanelViewModel()
{
Tabs.Add(new TabItem { Header = "One", Content = "One's content" });
Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" });
}
}
I cannot chare the engine code but, really, it is just a list of keys (RFID keys / EPC). This is the only public data. I want to display this list of key by group under my tabs.
Passing "this list or the entire engine reference" to the view defats the purpose of implementing the MVVM design pattern in the first place.
What you should do is to use the engine to prepare and set the state of your app/view in your view model.
The controls in the views should then bind to properties of the view model that contains, and effetively defines, the current state.

UI not updating using MVVM toolkit in WinUI 3

I am trying to change the size of a grid using data binding in order to be able to expand certain sections of my UI. I have looked online and nothing really seems to work. My window has a frame that loads a "root page" with another frame inside of it as seen in rootpage.xaml below. I have added a textbox but that does not seem to work. Interestingly enough, when I click the button present on the page. I do get a line outputted so my code is running. Adding a breakpoint shows similar results that the property FullScreenValue does in fact change. I think I am missing something in order to get the PropertyChanged event to be received or I may be unintentionally instancing multiple instances of my ViewModel. Looking for a solution.
My root page loaded into the frame in my window:
<Page
x:Class="MVVM.Views.rootPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MVVM.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModels="using:MVVM.ViewModels"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.DataContext>
<ViewModels:RootPageViewModel x:Name="ViewModel"/>
</Page.DataContext>
<Grid x:Name="frameGrid" ColumnDefinitions="*, *" RowDefinitions ="*, *" Grid.Row="1" Margin="15, 0, 15, 0" >
<Frame x:Name="topleftFrame" Grid.Column="0" Grid.Row="0" CornerRadius="8" Margin="10, 10, 10, 10" Grid.ColumnSpan="{Binding FullScreenValue,Mode=OneWay}" Grid.RowSpan="{Binding FullScreenValue, Mode=OneWay}"/>
<AppBarButton Icon="FullScreen" Grid.Column="0" Grid.Row="0" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,5,5,10" Command="{Binding FullScreenCommand, Mode=OneWay}"/>
Visibility="Visible"/>
<TextBlock Text="{Binding FullScreenValue, Mode=OneWay}" Grid.Row="1" Grid.Column="1"/>
</Grid>
</Page>
My ViewModel:
namespace MVVM.ViewModels
{
public partial class RootPageViewModel : ObservableObject
{
[ObservableProperty]
private int fullScreenValue;
public RootPageViewModel()
{
fullScreenValue = 1;
}
[ICommand]
void FullScreen()
{
fullScreenValue = 2;
Debug.WriteLine("HI");
}
}
}
As you can see I am trying to make use of the community toolkit. I have tried replacing some of these generated snippets with standard mvvm properties and commands to no avail. If I change the constructor to have a value of 2 I get my desired result, but can't seem to do it with this button! Send help.
My desired result is upon clicking the button, the frame will now span 2 columns and 2 rows instead of 1 column and 1 row. Maybe because this sort of UI concerns strictly the view it does not necessarily need a ViewModel but nonetheless I am still looking for help as I feel like I will run into this problem in the future. I am new to a lot of things in the Microsoft ecosystem so please forgive me if this is a repeat question and I just could not understand other answers.

MvvmCross Wpf View with Sub View

I have a working program in Caliburn Micro but am moving over to MvvmCross. What I have working in Caliburn is a ShellView (Parent) that displays my navigation buttons and a cart. On that view, there is another view which is my selection of the navigation buttons, let's call it ActiveView (the view changes, in Caliburn it was ActiveItem() to change the view).
In MvvmCross, I cannot get this same functionality to work. After 3 days of searching and reading, I need help. Here is the image of the program, Blue outline is ShellView, inside of it Red outline is ActiveView.
What I get with MvvmCross is the ShellView, with no ActiveView. So the parent works, but no child is displayed. I have created a few other MvvmCross apps but they contain no navigation.
I have 2 Code Versions, First works but creates a second Window. Second keeps a single Window, but does not navigate. I need a single window with navigation. I feel I have a core misunderstanding and cannot find a source that explains it.
First Sample Works, but creates 2 Windows. An empty window (from MainWindow.xaml) and a second from ShellView. My assumption for 2 Windows opening when app is ran, is MainWindow being a window, and ShellView also being set to Window in xaml and cs.
Based on MvvmCross Playground.Wpf
<views:MvxWindow
x:Class="MvxKioskMtg.Wpf.Views.ShellView"
xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
xmlns:mvx="clr-namespace:MvvmCross.Platforms.Wpf.Binding;assembly=MvvmCross.Platforms.Wpf"
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:MvxKioskMtg.Wpf.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="#3d3d3d"
>
<views:MvxWindow.ContentTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Content="Welcome" Command="{Binding ShowWindowChildCommand1}" Grid.Column="0"/>
<Button Content="Checkout" Command="{Binding ShowWindowChildCommand2}" Grid.Column="1"/>
</Grid>
<ContentPresenter Content="{Binding}" Grid.Row="1" />
</Grid>
</DataTemplate>
</views:MvxWindow.ContentTemplate>
</views:MvxWindow>
ShellView.xaml.cs
public partial class ShellView : MvxWindow
{
public ShellView()
{
InitializeComponent();
}
}
Second Version Layout looks correct, but no navigation. Click buttons has no effect. Adding break point to the Command that changes views and it is never reached.
XAML changed from MvxWindow to MvxWpfView in 4 places, otherwise same as First Version.
<views:MvxWpfView
<views:MvxWpfView.ContentTemplate>
</views:MvxWpfView.ContentTemplate>
</views:MvxWpfView>
ShellView.xaml.cs
public partial class ShellView : MvxWpfView
{
public ShellView()
{
InitializeComponent();
}
}
In the XAML, if I update the DataContect to AncestorType={x:Type views:MvxWpfView} from Window, it does update the View, but the entire View. Not the ContentPresenter space. So I lose my navigation buttons.
Which of these methods is correct, and what am I doing incorrect? Am I totally off base? Thank you for any help and guidance you can provide. I'll happily read any sources.

WPF window border acting weird with Ribbon Control

I am using the Ribbon control in WPF and I noticed there are 2 different versions.
using Microsoft.Windows.Controls.Ribbon;
If I use this one in my xaml and class, my whole window will be in a very old windows style.
using System.Windows.Controls.Ribbon;
If I use this one in my xaml and class, my Ribbontabs suddenly won't fill correctly anymore.
When I use both of them. With this:
<ribbon:RibbonWindow x:Class="WPSDashboard.Views.ShellWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Regions;assembly=Microsoft.Practices.Prism"
Title="WPSDashboard"
x:Name="RibbonWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Ribbon Region -->
<r:Ribbon x:Name="Ribbon" prism:RegionManager.RegionName="RibbonRegion">
<r:Ribbon.ApplicationMenu>
<r:RibbonApplicationMenu SmallImageSource="Images\SmallIcon.png">
<r:RibbonApplicationMenuItem Header="Exit"
x:Name="MenuItemExit"
ImageSource="Images\Exit.png"
Command="{Binding ExitCommand}"/>
</r:RibbonApplicationMenu>
</r:Ribbon.ApplicationMenu>
</r:Ribbon>
<Grid x:Name="ClientArea" Grid.Row="1">
<!-- Workspace Region-->
<GridSplitter HorizontalAlignment="Left" Width="2" Grid.Column="1"/>
<ContentControl x:Name="WorkspaceRegion" Grid.Column="1" prism:RegionManager.RegionName="WorkspaceRegion" />
</Grid>
</Grid>
</ribbon:RibbonWindow>
My Ribbontabs will load but the window now looks like this:
I can't click on close and minimize and maximize. <---
How can I get the border to be normal instead of small?
I can't close my windows this way.
I found the best way to make it look and work good!
Instead of the tags <ribbon:RibbonWindow on the beginning of the xaml,
Make it <Window .
Also add this part:
xmlns:r="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
Then in your class delete your : RibbonWindow (If it's there)
If that doesn't work and you don't need the quick access toolbar, this may help:
Go back to your XAML, and change the Ribbon margin to -22 :
<r:Ribbon x:Name="Ribbon" prism:RegionManager.RegionName="RibbonRegion" Margin="0,-22,0,0" >
Now my application looks like this(with the -22 margin) :
Now it looks like a normal application without an ugly windows 98 or 2000 style and the close button, minizime button and maximize button are back!
I personally would, either play on margins, or better than that, investigate the style of that ribbon and change it the way it helps my needs

How can i link a canvas on a grid, to the mainwindow.xaml?

I have a canvas in a grid, i want to keep my canvas on that grid, because its the first window, that opens in my program.
In my MainWindow.xaml, i have a ContentPage, that always changes its content, the startup content is the authenticationPage. In this page i have a Canvas that shows my skeletal tracking, and is used for making a gesture. This gestureCanvas is on my authenticationPage. The code behind this gestureCanvas is on my MainWindow.xaml.cs.
I need to link the gestureCanvas with my MainWindow.xaml.cs, because the code is behind MainWindow, and it's going to be used there, because it's an Kinect application.
How to link these ?
partial class MainWindow
{
void LoadCircleGestureDetector()
{
using (Stream recordStream = File.Open(circleKBPath, FileMode.OpenOrCreate))
{
circleGestureRecognizer.TraceTo(gesturesCanvas, Colors.Red);
}
}
}
This is my authenticationPage
<UserControl
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:smartHome2011"
xmlns:MyUserControl="clr-namespace:MyUserControl;assembly=MyUserControl"
mc:Ignorable="d"
x:Class="smartHome2011.AuthenticationPage"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid x:Name="kinectGrid" HorizontalAlignment="Left">
<Viewbox Margin="204,220,430,220">
<Grid ClipToBounds="True" Margin="204,220,430,220">
**<Canvas x:Name="gesturesCanvas" />**
<Canvas x:Name="kinectCanvas"></Canvas>
</Grid>
</Viewbox>
</Grid>
</Grid>
at your code behind MainWindow you can try following
var gesturesCanvas = YourContentPage.FindName("gesturesCanvas") as Canvas;
if (gesturesCanvas != null) {
// do something
}
hope this helps

Categories

Resources