Universal windows app to send data from one page to another - c#

I had partitioned the MainPage.xaml in two parts. The Left part has some buttons which will give command to change the Right part with new Page. So I created three right pages for ex. RightPage1, RightPage2 and RightPage3. The problem is that, I want to show data on Left part after the operations done on RightPage1, 2 or 3.
Should I follow some pattern to fulfill this approach? or we can do it directly in code behind?
All I researched is giving me solution to navigate to that page and send the data in parameter. But I don't want to open the page again, because it's already opened on the Left side of MainPage. Please help me to solve this situation.
In RightPage 1, on Submit Click Event I want to show some message in MainPage.xaml's Left part in TextBlock lblClassName.
HomePage.xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<RelativePanel>
<Button x:Name="btn1"
Content="Button 1"
Height="50" Width="100" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
Click="btn1_Click"/>
<Button x:Name="btn2"
Content="Button 2"
Height="50" Width="100" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="btn1"
Click="btn2_Click"/>
<Button x:Name="btn3"
Content="Button 3"
Height="50" Width="100" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="btn2"
Click="btn3_Click"/>
<TextBlock x:Name="lblWrite"
Text="Write something : "
Visibility="Visible"
RelativePanel.Below="btn3"/>
<TextBox x:Name="txtWrite"
Height="50" Width="150"
Visibility="Collapsed"
RelativePanel.Below="lblWrite"/>
<Button x:Name="btn3_1"
Height="50" Width="100"
Visibility="Collapsed"
Content="Send"
RelativePanel.Below="txtWrite"/>
<TextBlock x:Name="lblClassName"/>
</RelativePanel>
<Frame x:Name="RightPage"
Grid.Column="1"/>
</Grid>
RightPage1.xaml
<Grid Background="Beige">
<TextBlock x:Name="heading"
Text="Teacher Module"
RelativePanel.AlignHorizontalCenterWithPanel="True"/>
<TextBlock x:Name="lblName"
Text="Name" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="heading"/>
<TextBox x:Name="txtName"
Height="30" Width="150" Margin="30,30,0,0"
RelativePanel.RightOf="lblName"
RelativePanel.Below="heading"/>
<TextBlock x:Name="lblClass"
Text="Class" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="lblName"/>
<TextBox x:Name="txtClass"
Height="30" Width="150" Margin="30,10,0,0"
RelativePanel.RightOf="lblClass"
RelativePanel.Below="txtName"/>
<Button x:Name="btnSumbit"
Content="Submit"
Height="50" Width="100" Margin="0,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="lblClass"/>
<Button x:Name="btnCancel"
Content="Cancel"
Height="50" Width="100" Margin="30,30,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="lblClass"
RelativePanel.RightOf="btnSumbit"/>
<TextBlock x:Name="lblResult"
Margin="0,30,0,0"
RelativePanel.Below="btnSumbit"/>
</RelativePanel>
</Grid>

I think we can do it directly in code behind. For example:
In the code-behind of HomePage.xaml, we can define a static field in HomePage that represent the HomePage itself and add a public method to change the TextBlock's text.
public sealed partial class HomePage : Page
{
//define a static field represent the HomePage itself
public static HomePage Home;
public HomePage()
{
this.InitializeComponent();
//initialize Home field
Home = this;
}
...
/// <summary>
/// Show some message in TextBlock lblClassName
/// </summary>
/// <param name="message">message to been shown</param>
public void ChangeMessage(string message)
{
this.lblClassName.Text = message;
}
}
Then in Submit Click event, we can call ChangeMessage method to show the message.
private void btnSumbit_Click(object sender, RoutedEventArgs e)
{
HomePage.Home?.ChangeMessage("The message you want to show");
}

Related

Using MaterialDesignThemes DrawerHost

Please could someone assist me in trying to figure this out.
I have created a menu on a WPF page called DashView.xaml
this menu has buttons on it going down and I would like to know how to get the BottomDrawerContent to be visible once I click on a button.
Below I have given the code that is in DashView.xaml
<materialDesign:DialogHost x:Name="hostSales" >
<materialDesign:DrawerHost x:Name="SalesDrawerHost" Content="Sales" Foreground="GhostWhite"
FontWeight="Bold" FontSize="22" BottomDrawerCloseOnClickAway="True"
Cursor="Hand" Width="200" Height="30" ToggleButton.Checked="chkSalesBt1">
<materialDesign:DrawerHost.BottomDrawerContent x:Uid="dashSalesBt1">
<StackPanel x:Name="stkSalesBt1">
<Button Content="Record Sales" Foreground="GhostWhite" FontWeight="SemiBold"/>
<Button Content="Recent Sales" Foreground="GhostWhite" FontWeight="SemiBold"/>
</StackPanel>
</materialDesign:DrawerHost.BottomDrawerContent>
</materialDesign:DrawerHost>
</materialDesign:DialogHost>
I do have a class called DashClass.cs
Just not sure what I am meant to put in it or how I am meant to get the execution to show the BottomDrawerContent
Yout need a tooglebutton:
<ToggleButton
x:Name="menuToggler"
Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />`
and in the DrawerHost use IsLeftDrawerOpen
<materialDesign:DrawerHost
x:Name="SalesDrawerHost"
Content="Sales"
Foreground="GhostWhite"
FontWeight="Bold"
FontSize="22"
BottomDrawerCloseOnClickAway="True"
Cursor="Hand"
Width="200"
Height="30"
IsBottomDrawerOpen="{Binding ElementName=menuToggler, Path=IsChecked}">
<materialDesign:DrawerHost.BottomDrawerContent x:Uid="dashSalesBt1">
<StackPanel x:Name="stkSalesBt1">
<Button Content="Record Sales" Foreground="GhostWhite" FontWeight="SemiBold"/>
<Button Content="Recent Sales" Foreground="GhostWhite" FontWeight="SemiBold"/>
</StackPanel>
</materialDesign:DrawerHost.BottomDrawerContent>
</materialDesign:DrawerHost>

Get UserControls dynamically via XamlReader.Load, IsLoaded is false at UI Elements

I try to save and load TabItems via XamlWriter and XamlReader at runtime so that the user can restore the previous session. Each TabItem consists of UserControls and standard WPF controls like grids,buttons and checkboxes.
It all works fine until I try to subscribe to events of let's say a button.
If I raise them manually with RaiseEvent() they work, but if I click on them nothing happens. Even if I set IsEnabled=false the button is displayed as enabled. LogicalTreeHelper.FindLogicalNode gives me the right button, but the Click event also won't trigger. The IsLoaded property is false, so I assume there has to be some underlying problem with the initialization.
Basically this is the code to read from the file
StreamReader sw = new StreamReader(file);
XmlReader xmlReader = XmlReader.Create(sw);
TabItem tabItem = (TabItem)XamlReader.Load(xmlReader);
.. and this to save each TabItem to a seperate xml file
foreach (TabItem tabItem in tabControlMain.Items)
{
StreamWriter sw = new StreamWriter(Path.Combine(path,tabItem.Name + ".xml"), false);
string savedTab = XamlWriter.Save(tabItem);
sw.Write(savedTab);
sw.Close();
}
Here is an example TabItem saved to a file
<TabItem IsSelected="True" Header="Test" Name="tabItem1" HorizontalAlignment="Left" VerticalAlignment="Top" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:womoc="clr-namespace:WeldOsMqttOpcClient;assembly=blabla">
<TabItem.HeaderTemplate>
<DataTemplate DataType="{x:Type TabItem}">
<TextBox Margin="0,0,30,0" Text="{Binding Path=.}" />
</DataTemplate>
</TabItem.HeaderTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<womoc:UcOverviewTabPage Autoconnect="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Name="gridParentOv">
<Grid Name="gridMqttOpcControls" Height="599.08" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<womoc:UcConnection Name="ucOpc" MinWidth="400" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<GroupBox Header="OPC [10.5.51.130]" Name="groupBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer>
<Grid Name="gridTextBoxesWithValues" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Name="rowLabel" />
</Grid.RowDefinitions>
<Label Background="#FF008000" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Name="labelConnected" Width="190" Height="26" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.ColumnSpan="2">Connected!</Label>
</Grid>
</ScrollViewer>
</GroupBox>
</womoc:UcConnection>
</Grid>
<Grid Name="gridConnection" MinHeight="30" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Button Name="btnConnect" Width="55" Margin="100,0,0,10" HorizontalAlignment="Center" VerticalAlignment="Bottom" IsEnabled="False">Connect</Button>
<TextBox Name="tbIPAddress" Width="95" Height="18" Margin="0,0,100,10" HorizontalAlignment="Center" VerticalAlignment="Bottom" IsEnabled="False">10.5.51.130</TextBox>
<CheckBox Name="cbMqtt" Width="46" Height="15" Margin="20,0,0,10" HorizontalAlignment="Left" VerticalAlignment="Bottom" IsEnabled="False">Mqtt</CheckBox>
<CheckBox IsChecked="True" Name="cbOpc" Width="42" Margin="0,0,20,10" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsEnabled="False">Opc</CheckBox>
</Grid>
</Grid>
</womoc:UcOverviewTabPage>
</Grid>
</TabItem>
UcOverviewTabPage is one of my UserControls, in which there is for example a button. I try to subscribe to the events manually ->
public UcOverviewTabPage()
{
InitializeComponent();
cbMqtt.Checked += CbMqtt_Checked;
cbMqtt.Unchecked += CbMqtt_Unchecked;
cbOpc.Checked += CbOpc_Checked;
cbOpc.Unchecked += CbOpc_Unchecked;
btnConnect.Click += BtnConnect_Click;
var children = LogicalTreeHelper.FindLogicalNode(this, "btnConnect") as Button;
bool loaded = children.IsLoaded;
// -> FALSE
}
Bear in mind, creating new custom UserControls during runtime works perfectly. The problem only occurs when reading out of the XML file.
I except the UserControls or any other Controls to work like they do when created during runtime. What am I missing?

Adding and editing item in datagrid with same controls

Hei,
I'm using MVVM with my wpf application. I have DataGrid what shows list of items and i have binded SelectedItem to CurrentSequence propery in my ViewModel. When CurrentSequence changes properties of that object are shown in other controls for editing.
Heres my xaml:
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=ColorSettingsSequences}"
SelectedItem="{Binding Path=CurrentSequence, Mode=TwoWay}">
.... more things here ...
</DataGrid>
<StackPanel Grid.Column="0" Grid.Row="0">
<Grid>
<Label Content="Start temperature (°C)" Height="28" HorizontalAlignment="Left" x:Name="lblSeqStartTemp" VerticalAlignment="Top" />
<TextBox Height="23" Margin="0,28,10,0" x:Name="tbSeqStartTemp" VerticalAlignment="Top" Text="{Binding Path=CurrentSequence.StartTemp}" />
</Grid>
<Grid>
<Label Content="Start color" Height="28" HorizontalAlignment="Left" x:Name="lblSeqHue" VerticalAlignment="Top" />
<xctk:ColorPicker Margin="0,28,10,0" x:Name="clrpSeqHue" SelectedColor="{Binding Path=CurrentSequence.StartHue, Converter={StaticResource hueToColor}, ConverterParameter=False}" ShowStandardColors="False" />
</Grid>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0">
<Grid>
<Label Content="End temperature (°C)" Height="28" HorizontalAlignment="Left" x:Name="lblSeqEndTemp" VerticalAlignment="Top" />
<TextBox Height="23" Margin="0,28,10,0" x:Name="tbSeqEndTemp" VerticalAlignment="Top" Text="{Binding Path=CurrentSequence.EndTemp}" />
</Grid>
<Grid>
<Label Content="End color" Height="28" HorizontalAlignment="Left" x:Name="lblSeqEndHue" VerticalAlignment="Top" />
<xctk:ColorPicker Margin="0,28,10,0" x:Name="clrpSeqEndHue" SelectedColor="{Binding Path=CurrentSequence.EndHue, Converter={StaticResource hueToColor}, ConverterParameter=False}" ShowStandardColors="False" />
</Grid>
</StackPanel>
Code:
private ColorSettingsSequencesSequence _currentSequence;
public ColorSettingsSequencesSequence CurrentSequence
{
get
{
return this._currentSequence;
}
set
{
this._currentSequence = value;
OnPropertyChanged("CurrentSequence");
}
}
Now the questions is, how could i add a button what would save changes or add a totally new item. I know how to do one or another, but what about 2 together with same controls...
You can create a property on your view model which is of type ColorSettingsSequencesSequence named CurrentSequenceEdit and you can set the value of this object upon changing selection.
Then upon click of an add button you can create a new ColorSettingsSequencesSequence object and set it to the value of CurrentSequenceEdit.
Typically on a new object you'll have an ID that is not set or is set to a negative number which you can use in the Save command to determine whether it needs added to the grid or not.

No success binding an Image

I am trying to bind an image on the main window with a string (stored in another class) which represents the file path of the image I want to display.
But nothing shows up.
Here is my main window code xaml code:
<HierarchicalDataTemplate x:Key="categoryTemplate"
ItemsSource="{Binding Path=Items}"
ItemTemplate="{StaticResource animalTemplate}">
<Grid MouseEnter="DockPanel_MouseEnter" MouseLeave="DockPanel_MouseLeave">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="16" />
</Grid.ColumnDefinitions>
<Image HorizontalAlignment="Center" Source="{Binding Path=IconFilePath}" VerticalAlignment="Center" Width="16" Height="16" Grid.Column="0" />
<TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" FontWeight="Bold" FlowDirection="{Binding Path=FlowDirection}" FontSize="14" HorizontalAlignment="Stretch" Grid.Column="1" />
<Border CornerRadius="2" Background="Lavender" Grid.Column="2" Margin="0,0,5,0">
<TextBlock Text="30" Foreground="DodgerBlue" HorizontalAlignment="Center" FontWeight="Bold" FontSize="13" />
</Border>
<aea:MenuButton Margin="0,0,2,0" Opacity="0" HorizontalAlignment="Right" Grid.Column="3" SnapsToDevicePixels="False" Width="16" Height="16" DisplayStyle="Text" IsEnabled="True" IsDropDownOpen="False">
<aea:SplitButtonItem IsSelected="True" Visibility="Collapsed">
<Image HorizontalAlignment="Center" Source="Assets\FeedMenu.png" VerticalAlignment="Center"/>
</aea:SplitButtonItem>
<aea:SplitButtonItem Tag="{Binding Path=me}" Selected="Subscription_MarkAllAsRead">Mark all as Read</aea:SplitButtonItem>
<aea:SplitButtonItem Tag="{Binding Path=me}" Selected="Subscription_AddAllToFavorites">Add all to Favorites</aea:SplitButtonItem>
<aea:SplitButtonItem Tag="{Binding Path=me}" Selected="Subscription_ReadAllLater">Read all Later</aea:SplitButtonItem>
<aea:SplitButtonItem Tag="{Binding Path=me}" Selected="Subscription_OpenAllBrowser">Open all in browser</aea:SplitButtonItem>
</aea:MenuButton>
</Grid>
<!--<TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/>-->
</HierarchicalDataTemplate>
Here is my other class:
public string IconFilePath { get; private set; }
public Subscription()
{
this.IconFilePath = #"C:\Users\Din\Din\Programming\Webs\Ended Projects\CodeCaged\Products\Read 360\Read 360\Read 360\bin\Release\feeds\1.ico";
}
You are binding relative to the DataContext so you need to make sure its an instance of that class. Also check for binding errors, not more to be said with this little context.
It is hard without a full code listing of how this control is setup (e.g. where and how is the DataContext set?, and how is the list of 'Items' populated?)
But on the surface it appears you're expecting to get both 'Name' and 'IconFilePath' from an Items element, so to confirm the Subscription Class defines both IconFilePath and Name?
A tool like Snoop can automatically display binding errors in a running applications visual tree; and I would expect it to list such in this case.
Also to reduce possible headaches (and this may well be the issue) it may be worth mentioning INotifyPropertyChanged for your data class. Property changes on your data class will not automatically progate otherwise.

wpf page not editable

I have a problem trying to develop a WPF page. I have a window with a WPF Frame, when the window is loaded i use MainFrame.Navigate(new page object). The only problem is i can not press any button or use a textbox. Any idea, how can i solve this?
here is the code of my wpf window:
<Window x:Class="ViewLayer.Forms.Win_LoginCloseable"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Win_LoginCloseable" Height="477" Width="501" WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="180*" />
<RowDefinition Height="164*" />
<RowDefinition Height="35*" />
</Grid.RowDefinitions>
<Rectangle Grid.RowSpan="3" Name="Rect_Main" />
<TextBlock Grid.Row="2" FontFamily="Calibri" FontSize="17" FontStyle="Italic" Margin="10,0,12,7" Name="tb_remainding" Text="" TextAlignment="Justify" TextWrapping="WrapWithOverflow" Height="28" VerticalAlignment="Bottom" />
<Button Content="Cerrrar" Grid.Row="1" Height="73" HorizontalAlignment="Center" Name="btn_cancel" VerticalAlignment="Bottom" Width="173" Click="btn_cancel_Click" Background="#FFC70000" Margin="114,0,114,5" />
<Frame x:Name="MainFrame" IsHitTestVisible="False" NavigationUIVisibility="Automatic" />
<TextBlock FontFamily="Calibri" FontSize="22" FontWeight="Bold" Foreground="#FF797979" Height="95" Margin="0,0,0,0" Name="textBlock2" Text="Una vez identificado, luego de 90 segundos de inactividad el sistema cerrará su sesión automaticamente" TextAlignment="Center" TextTrimming="None" TextWrapping="Wrap" VerticalAlignment="Top" Grid.Row="1" HorizontalAlignment="Center" />
<TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="34,100,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
the constructor of the window
private Win_LoginCloseable()
{
InitializeComponent();
this.Pages = new List<Page>();
this.Pages.AddRange(new Page[]{
new MagneticCardPage(),
new UserInputPage()
});
}
here when i load the form:
public void LoadForm(int Index = 0)
{
this.MainFrame.Navigate(this.Pages[Index]);
this.ShowDialog();
}
i repeat, in a page i have textboxs and buttons. But when i try to use them or clicked i can. The events are not getting to the pages.
Thanks in advance
Your code in the constructor is wrong. It should be marked public, instead of private.
The constructor will always call InitializeComponent, but it can't function normally if your constructor is marked as private. Therefore, the control will be displayed BUT the event handle will not be executed, because event handler code is available inside InitializeComponent, and I'm sure it won't be executed.
Change this:
private Win_LoginCloseable()
{
InitializeComponent();
this.Pages = new List<Page>();
this.Pages.AddRange(new Page[]{
new MagneticCardPage(),
new UserInputPage() });
}
Into this:
public Win_LoginCloseable()
{
InitializeComponent();
this.Pages = new List<Page>();
this.Pages.AddRange(new Page[]{
new MagneticCardPage(),
new UserInputPage() });
}
Well! I Figure out the solution of the problem.
here:
<Frame x:Name="MainFrame" IsHitTestVisible="False" NavigationUIVisibility="Automatic" />
i replace it with:
<Frame x:Name="MainFrame" IsManipulationEnabled="True" />
and it works well!
Thanks!

Categories

Resources