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!
Related
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?
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");
}
Hello I am working with windows phone 8.1[RT] application , I simply navigate page only . but I found new option we can use Frame in xaml also like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Background="White">
</Border>
<Button Content="next" Click="Button_Click" Background="Black" />
<Grid Grid.Row="1">
<Frame x:Name="Page1Frame" Background="Black" >
<StackPanel>
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
</StackPanel>
</Frame>
</Grid>
</Grid>
and navigate this frame like this
private void Button_Click(object sender, RoutedEventArgs e)
{
Page1Frame.Navigate(typeof(BlankPage1));
}
in this example my 120 height grid remain same and just navigate the frame .
I just want to know which is best practice to use ?
Thank you.
Page is page, Frame is frame, they are different.
Suppose your current page named MainPage, if you want to stay in MainPage and change the content of grid in root grid's row 1, you should use:
Page1Frame.Navigate(typeof(BlankPage1));
If you want to leave MainPage to go to another page, you should use:
var rootFrame = Window.Current.Content as Frame;
rootFrame.Navigate(typeof(BlankPage1));
and in this case, what you see is a blank page without 120 height grid remain.
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.
I have this window defined in C#:
<Window x:Class="VirginOneAccount.AccountInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Account Information" Height="362" Width="614" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="AccountTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AccountName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="418*" />
<ColumnDefinition Width="174*" />
</Grid.ColumnDefinitions>
<ComboBox Height="23" HorizontalAlignment="Stretch" Margin="40,16,42,0" Name="AccountsList" VerticalAlignment="Top" Width="Auto" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}" ItemTemplate="{StaticResource AccountTemplate}" AllowDrop="False" DataContext="{Binding}" IsEnabled="True" SelectionChanged="AccountsList_SelectionChanged" />
<Button Content="Save Changes" Height="23" HorizontalAlignment="Left" Margin="40,0,0,10" Name="saveChanges" VerticalAlignment="Bottom" Width="90" IsEnabled="False" Click="saveChanges_Click" />
</Grid>
Then in the main form, I call Show() on an instance of the window:
AccountInfo Accounts = new AccountInfo();
Accounts.Show();
But all I see is an empty window (not even the right size). Why isn't it opening my window?
I did a simple window and this worked for me. Take it down to just a textbox and see if it works.
public MainWindow()
{
InitializeComponent();
Window1 win1 = new Window1();
win1.Show();
}
The window class name may be different between the xaml definition and the code behind file.
Example
telerik:RadWindow x:Class="MyWindow"
vs
public partial class My_Window : RadWindow
{
public My_Window()
{
InitializeComponent();
}
}
In this case the initializeComponent() call is unrecognized by the compiler