Initialization of 'System.Windows.Controls.Button' threw an exception - c#

I am creating a WPF on which, i have 2 threads. One is the main, and the other one(called PillTimeOutChecker) check some requirements in the main form. If the requirements meet, a new form through the PilleCheckerThread show up in a new thread. The problem is that i am getting this error: Initialization of 'System.Windows.Controls.Button' threw an exception in the initialization of the new form.
This is the method in the main thread, that call the PillCheckerThread:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Thread PillChecker = new Thread(new ThreadStart(PillCheckerThread));
PillChecker.SetApartmentState(ApartmentState.STA);
PillChecker.IsBackground = true;
PillChecker.Name = "PillTimeOutChecker";
PillChecker.Start();
}
This is the content of the PillCheckerThread method:
private void PillCheckerThread()
{
foreach (DataGridObject item in PillList.Items)
{
if(item.DoIt)
{
//Show PillWarning window
Thread PillWarningWindow = new Thread(new ThreadStart(() =>
{
PillWarningWindow pl = new PillWarningWindow(item.PillName, item.AlertTime);
pl.Show();
System.Windows.Threading.Dispatcher.Run();
}));
PillWarningWindow.SetApartmentState(ApartmentState.STA);
PillWarningWindow.IsBackground = true;
PillWarningWindow.Start();
}
}
}
This is the content of the PillWarningWindow:
public partial class PillWarningWindow : Window
{
public PillWarningWindow(string PillName, string CurrentTime)
{
InitializeComponent();
PillNameLbl.Content = PillName;
TimeLbl.Content = CurrentTime;
}
private void CloseBtn_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
This is the xaml of the PillWarningWindow:
<Window x:Class="MedicalReminder.PillWarningWindow"
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:MedicalReminder"
mc:Ignorable="d" Height="300" Width="713.414" ShowInTaskbar="False" Topmost="True" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None" Background="Transparent" AllowsTransparency="True">
<Border BorderBrush="Black" CornerRadius="20" Background="DarkCyan">
<Grid>
<Button x:Name="CloseBtn" Content="OK" HorizontalAlignment="Left" Margin="262,239,0,0" VerticalAlignment="Top" Width="179" Click="CloseBtn_Click"/>
<Label x:Name="label" Content="Psssttt !! It's time to take your pill: " HorizontalAlignment="Left" Margin="89,93,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="18"/>
<Label x:Name="PillNameLbl" Content="PillName" HorizontalAlignment="Left" Margin="395,93,0,0" VerticalAlignment="Top" FontSize="18" FontWeight="Bold"/>
<Label x:Name="label2" Content="It's exactly " HorizontalAlignment="Left" Margin="89,132,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="18"/>
<Label x:Name="TimeLbl" Content="12:00" HorizontalAlignment="Left" Margin="195,133,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="17" Width="56"/>
<Label x:Name="label3" Content="you forgot it ??" HorizontalAlignment="Left" Margin="256,132,0,0" VerticalAlignment="Top" FontWeight="Bold" FontSize="18"/>
</Grid>
</Border>
With a breakpoint at the constructor of the PillWarningWindow i found out that the error start at the InitializeComponent method. Any help is appreciated. Thanks.

If you want to access windows propety you should use Dispatchers.
Because of another thread cannot acces window directly. You can use the Dispatcher when you want to run an operation that will be executed on the UI thread.
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => PillNameLbl.Content = PillName;
TimeLbl.Content = CurrentTime));

If debugger stops at InitializeComponent method, I'd say there is probably something wrong with your XAML code (which despite of being full of bad practices, doesn't seem to be incorrect). Are you sure your controls don't have style resources defined in any other place? I have had the same error before and it was caused by defining styles in a wrong order.
Try to launch your window directly at the application start instead of launching it from another thread, just to test if it's OK. If it works, then the problem is in the thread management.

Related

Window.ShowDialog failes on return

I have a custom input dialog box that request an user's name and a reson (because reasons) for doing a certain action in my application. The user clicks on a button on the main window and the dialog box shows, as it should.
The user then enters his/her name and the reason and clicks ok. The dialog then closes but I ( the program) never receives an answer. Here is my XAML for the input dialog:
<Window x:Class="Sequence_Application_2.GUI.ForcedRackInput"
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="Forcera Rack" Height="300" Width="300"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="21*"/>
<ColumnDefinition Width="274*"/>
</Grid.ColumnDefinitions>
<TextBox Name="OperatorNameText" HorizontalAlignment="Left" Height="23" Margin="15,36,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2"/>
<Label x:Name="label" Content="Namn:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<Label x:Name="label1" Content="Orsak:" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<Border BorderThickness="1" BorderBrush="Black" Grid.ColumnSpan="2" Margin="0,0,0,0.5">
<TextBox Name="ReasonText" Margin="15,98,15,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="116" />
</Border>
<Button Name="OkButton" IsDefault="True" Content="OK" Click="OkButtonPressed" HorizontalAlignment="Left" Margin="26.202,233,0,0" VerticalAlignment="Top" Width="75" Cursor="Arrow" Grid.Column="1"/>
<Button Name="CancelButton" IsCancel="True" Content="Avbryt" Margin="152.202,233,47,0" VerticalAlignment="Top" Cursor="Arrow" Grid.Column="1"/>
</Grid>
</Window>
And here is the "behind code":
namespace Sequence_Application_2.GUI
{
using System.Windows;
public partial class ForcedRackInput : Window
{
public string OperatorName { get { return OperatorNameText.Text; } }
public string ForcedRackReason { get { return ReasonText.Text; } }
public ForcedRackInput()
{
InitializeComponent();
}
private void OkButtonPressed(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
}
}
and this is how I call the code (from a model, not a "window class")
public void ForceClosingRack(Flow forcedFlow)
{
var forcedRackWindow = new ForcedRackInput();
string operatorName = "";
string reasonForForced = "";
if( forcedRackWindow.ShowDialog() == true)
{
operatorName = forcedRackWindow.OperatorName;
reasonForForced = forcedRackWindow.ForcedRackReason;
}
} // code jumps from "if(forcedRackWindow.... to this line when ok is clicked in the dialog
Looked for the solution for some time now and I just about to change career
Thanks for your time
My guess is that the problem doesn't lie in the code, which seems to be fine, but in your if statement.
When you run your program in Debug mode it should work as expected.
My guess is that you are assigning the variables operatorName and reasonForForced inside your if statment but they are not used anywhere else in the program and hence the whole if statement is ignored by the compiler and not present when running in Release mode.
A small modification in your code which embeds different behaviour depending on the variable values can prove my guess:
private void Button_Click(object sender, RoutedEventArgs e)
{
var forcedRackWindow = new ForcedWindow();
string operatorName = "foo";
string reasonForForced = "foo";
if (forcedRackWindow.ShowDialog() == true)
{
operatorName = forcedRackWindow.OperatorName;
reasonForForced = forcedRackWindow.ForcedRackReason;
}
if(!operatorName.Equals(reasonForForced))
{
MessageBox.Show("We are not the same");
}
}

'MouseEventArgs' does not contain a definition for 'GetPosition'

Im sure this is a super easy one but I am working on a C# UWP app and am trying to make a drag-able user control but in my mouse event I'm getting the following error:
CS1061 'MouseEventArgs' does not contain a definition for 'GetPosition' and no extension method 'GetPosition' accepting a first argument of type 'MouseEventArgs' could be found (are you missing a using directive or an assembly reference?)
I found this example I am using on stack (Dragging a WPF user control) and have used mouse down events before for dragging items between list boxes in winforms but didn't have this issue.
Here is my code:
<UserControl
x:Class="HopHaus.TimerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HopHaus"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400" Width="120" Height="60">
<Grid Margin="0,0,0,167" Width="120">
<Rectangle Fill="#FF404040" HorizontalAlignment="Left" Height="60" Margin="1,0,-1,-133" Stroke="Black" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="timersetBox" Margin="-1,-2,1,-59" TextWrapping="Wrap" Text="00" VerticalAlignment="Top" Height="60" BorderBrush="Transparent" FontFamily="Fonts/DIGITAL.TTF#Digital" Foreground="#FF72FB00" FontSize="50" Background="Transparent" TextAlignment="Right" AcceptsReturn="True" SelectionHighlightColor="#000078D7" Width="120"/>
<Border x:Name="dragBrdr" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="59" Margin="2,0,0,-59" VerticalAlignment="Top" Width="118"/>
</Grid>
</UserControl>
And:
public sealed partial class TimerControl : UserControl
{
Point currentPoint;
Point anchorPoint;
bool isInDrag;
public TimerControl()
{
this.InitializeComponent();
}
private TranslateTransform transform = new TranslateTransform();
private void root_MouseMove(object sender, MouseEventArgs e)
{
if (isInDrag)
{
var element = sender as FrameworkElement;
currentPoint = e.GetPosition(null);
transform.X += currentPoint.X - anchorPoint.X;
transform.Y += (currentPoint.Y - anchorPoint.Y);
this.RenderTransform = transform;
anchorPoint = currentPoint;
}
}
}
I am using both using System.Windows.Input & using Windows.Devices.Input
Thanks a bunch in advance for any help provide.
To have better support for touch and inking there is an abstraction over the mouse events. This is called pointer. So in you you have a PointerMoved event
in xaml:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
PointerMoved="Grid_PointerMoved">
</Grid>
and in code
private void Grid_PointerMoved(object sender, PointerRoutedEventArgs e)
{
var point = e.GetCurrentPoint(null);
}
but am still unsure how to take my var point and transform it into a new position of my user control on my MainPage
As #Dave Smits said you need a Pointer event handle. More details about handle pointer input please reference this document. I think what you confused is that this code var point = e.GetCurrentPoint(null); return PointerPoint object instead Point structure what you needed for transform. In that case, you can get the Point structure by PointerPoint.Position property. Updated code as follows:
<UserControl
...
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
Width="120" Height="60" PointerMoved="Grid_PointerMoved" CanDrag="True">
<Grid Margin="0,0,0,167" Width="120" >
<Rectangle Fill="#FF404040" HorizontalAlignment="Left" Height="60" Margin="1,0,-1,-133" Stroke="Black" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="timersetBox" Margin="-1,-2,1,-59" TextWrapping="Wrap" Text="00" VerticalAlignment="Top" Height="60" BorderBrush="Transparent" FontFamily="Fonts/DIGITAL.TTF#Digital" Foreground="#FF72FB00" FontSize="50" Background="Transparent" TextAlignment="Right" AcceptsReturn="True" SelectionHighlightColor="#000078D7" Width="120"/>
<Border x:Name="dragBrdr" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="59" Margin="2,0,0,-59" VerticalAlignment="Top" Width="118"/>
</Grid>
</UserControl>
Code behind
Point currentPoint;
Point anchorPoint;
bool isInDrag;
private TranslateTransform transform = new TranslateTransform();
private void Grid_PointerMoved(object sender, PointerRoutedEventArgs e)
{
anchorPoint = new Point(300, 200);
isInDrag = true;
if (isInDrag)
{
var element = sender as FrameworkElement;
PointerPoint currentPointpointer = e.GetCurrentPoint(null);
currentPoint = currentPointpointer.Position;
transform.X += currentPoint.X - anchorPoint.X;
transform.Y += (currentPoint.Y - anchorPoint.Y);
this.RenderTransform = transform;
anchorPoint = currentPoint;
}
}
Additionally, for transform from one point to another I recommend you to use PointAnimation.

WPF NavigationService is null

I'm learning WPF (moving from Procedural PHP) and have written the following to navigate from 'MainWindow' to 'Page1', where there are no errors with the login credentials, but the local variable 'nav' is always null (hence displaying an error message):
namespace YM_POS_20160229_0949
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void ClickLoginSubmitButton(object sender, RoutedEventArgs e)
{
// Dictionary object is c# equivalent of PHP's 'array["key"] = "value"'
Dictionary<string, string> errMsg = new Dictionary<string, string>();
// declare variables
string varUserName;
string varUserPass;
// define the variables whilst trimming the values passed
varUserName = LoginUsername.Text.Trim();
varUserPass = LoginPassword.Password.Trim();
// ensure something has been submitted & perform validation on the values submitted
// if there are no errors, navigate to the users dashboard (aka Page1)
NavigationService nav = NavigationService.GetNavigationService(new Page1());
// check if the nav variable is populated
if (nav != null)
{
nav.Navigate(nav);
}
else
{
// display an error message to the user advising them an error has occurred and Page1 is not available
MessageBox.Show("An error has occured. unable to proceed to " + nav);
}
}
}
}
Any help greatly appreciated.
Thanks
Newbie Matt
//UI / XAML
<Window x:Class="YM_POS_20160229_0949.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:local="clr-namespace:YM_POS_20160229_0949"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="123*"/>
<ColumnDefinition Width="394*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="LoginUsername" HorizontalAlignment="Left" Height="23" Margin="56.649,55,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Grid.Column="1"/>
<PasswordBox x:Name="LoginPassword" HorizontalAlignment="Left" Height="23" Margin="56.649,100,0,0" Password="Password" VerticalAlignment="Top" Width="120" Grid.Column="1" />
<Button x:Name="LoginSubmitButton" Content="Submit" HorizontalAlignment="Left" Margin="81.649,172,0,0" VerticalAlignment="Top" Width="75" Click="ClickLoginSubmitButton" Grid.Column="1"/>
</Grid>
</DockPanel>
</Window>

C# User Must Add Multiple Buttons to WPF and Buttons Must Persist

I am attempting to create a program in which the User can create multiple profiles. These profiles can be accessed via buttons that appear as each profile is completed.
My problem:
I have no clue how to make the created buttons persist after the program is exited(I need to save the buttons?)
Visually, this is program's process: 1) Enter your information, click continue 2) View a display page of what you entered, click done. 3) This adds a button to the final window, the button of course takes you to 4) Your profile you just created.
After this, the program ends and nothing is saved. I'm fairly new to c# and am quite confused on how to "save" multiple buttons without massively complicating the code. I'm a complete noob to c# and have a little Java experience. Am I going about this correctly? I'm pretty sure its possible but have no idea to go about it.
I will include my code below. I'm working in visual studios 2012. any help would be appreciated!
MainWindow XAML:
<Window x:Class="VendorMain.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Content="FirstName" HorizontalAlignment="Left" Margin="63,45,0,0" VerticalAlignment="Top"/>
<Label Content="LastName" HorizontalAlignment="Left" Margin="63,71,0,0" VerticalAlignment="Top"/>
<Label Content="Image" HorizontalAlignment="Left" Margin="63,102,0,0" VerticalAlignment="Top"/>
<Image Name="imgPhoto" Stretch="Fill" Margin="63,133,303,69"></Image>
<Button Name="UploadImageButton" Content="Upload Image" HorizontalAlignment="Left" Margin="130,105,0,0" VerticalAlignment="Top" Width="84" Click="UploadImageButton_Click"/>
<TextBox Name="AssignFirstName" Text="{Binding SettingFirstname}" HorizontalAlignment="Left" Height="23" Margin="130,48,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
<TextBox Name="AssignLastName" Text="{Binding SettingLastName}" HorizontalAlignment="Left" Height="23" Margin="130,75,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Button Name="ContinueToDisplayWindow" Content="Continue" HorizontalAlignment="Left" Margin="409,288,0,0" VerticalAlignment="Top" Width="75" Click="ContinueToDisplayWindow_Click" />
</Grid>
MainWindow Code:
namespace VendorMain
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void UploadImageButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog op = new OpenFileDialog();
op.Title = "Select a picture";
op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)|*.png";
if (op.ShowDialog() == true)
{
imgPhoto.Source = new BitmapImage(new System.Uri(op.FileName));
//SettingImage.Source = imgPhoto.Source;
}
}
private void ContinueToDisplayWindow_Click(object sender, RoutedEventArgs e)
{
DisplayPage displaypg = new DisplayPage();
displaypg.DpFirstName.Content = AssignFirstName.Text;
displaypg.DpLastName.Content = AssignLastName.Text;
displaypg.DpImage.Source = imgPhoto.Source;
displaypg.Show();
}
}
}
DisplayPage XAML:
<Window x:Class="VendorMain.DisplayPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DisplayPage" Height="300" Width="525">
<Grid>
<Label Name="DpFirstName" Content="{Binding getFirstNamePermenent}" HorizontalAlignment="Left" Margin="86,55,0,0" VerticalAlignment="Top"/>
<Label Name="DpLastName" Content="{Binding getLastNamePermenent}" HorizontalAlignment="Left" Margin="87,80,0,0" VerticalAlignment="Top"/>
<Image Name="DpImage" HorizontalAlignment="Left" Height="100" Margin="94,111,0,0" VerticalAlignment="Top" Width="100"/>
<Button Name="ButtonizeThisProfile_Button" Content="Done" HorizontalAlignment="Left" Margin="420,238,0,0" VerticalAlignment="Top" Width="75" Click="ButtonizeThisProfile_Button_Click"/>
</Grid>
DisplayPage Code:
namespace VendorMain
{
/// <summary>
/// Interaction logic for DisplayPage.xaml
/// </summary>
public partial class DisplayPage : Window
{
public Button bot1;
public DisplayPage()
{
InitializeComponent();
}
private void newBtn_Click(object sender, RoutedEventArgs e)
{
carryToFinalView();
}
private void ButtonizeThisProfile_Button_Click(object sender, RoutedEventArgs e)
{
UserProfiles uPro = new UserProfiles();
System.Windows.Controls.Button newBtn = new Button();
newBtn.Content = "Person1";
newBtn.Name = "NewProfileButtonAccess";
newBtn.Click += new RoutedEventHandler(newBtn_Click);
uPro.ButtonArea.Children.Add(newBtn);
uPro.Show();
}
public void carryToFinalView()
{
DisplayPage displaypg = new DisplayPage();
displaypg.DpFirstName.Content = DpFirstName.Content;
displaypg.DpLastName.Content = DpLastName.Content;
displaypg.DpImage.Source = DpImage.Source;
displaypg.Show();
}
}
}
UserProfile XAML:
<Window x:Class="VendorMain.UserProfiles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="UserProfiles" Height="300" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".8*" />
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="6*"/>
<RowDefinition Height="11*"/>
</Grid.RowDefinitions>
<Label Content="User Profiles: " HorizontalAlignment="Left" Margin="37,47,0,0" VerticalAlignment="Top"/>
<StackPanel Name="ButtonArea" Grid.Column="2" Grid.Row="2">
</StackPanel>
<Button Name="AddAnotherProfileButton" Content="Button" HorizontalAlignment="Left" Margin="35,146,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="AddAnotherProfileButton_Click"/>
</Grid>
UserProfile Code:
namespace VendorMain
{
public partial class UserProfiles : Window
{
public UserProfiles()
{
InitializeComponent();
}
private void AddAnotherProfileButton_Click(object sender, RoutedEventArgs e)
{
MainWindow mw = new MainWindow();
mw.Show();
}
}
}
As a self proclaimed 'noob', I fear that you won't receive an answer here. I certainly don't have time to repeatedly come back to answer a whole continuing stream of related questions. I also don't have time to provide you with a complete solution. However, I am happy to provide you with sort of 'pseudo code' to at least point you in the right direction... you will have to do a lot of this yourself.
So first things first, as mentioned in a comment, although it is possible, we don't generally save the UI Button objects, but instead we save the data that relates to the user profiles. Therefore, if you haven't done this already, create a User class that has all of the relevant properties. Implement the INotifyPropertyChanged Interface in it and add the SerializableAttribute to the class definition... this will enable you to save this class type as binary data.
Next, in your UI, don't add each Button in xaml... there's a better way. One way or another, add a collection property of type User or whatever your class is called, and set this as the ItemsSource of a ListBox. The idea here is to add a DataTemplate for your User type which will display each of the User items in the collection as a Button:
<DataTemplate x:Key="UserButtonTemplate" DataType="{x:Type DataTypes:User}">
<Button Text="{Binding Name}" Width="75" Click="AddAnotherProfileButton_Click" />
</DataTemplate>
You can find out more about DataTemplates in the Data Templates article.
Implementing this collection allows you to have and display any number of user profiles in your UI, rather than being restricted by screen size as your original example would be.
Now finally, on to saving the data... this can be achieved relatively simply using the following code:
try
{
using (Stream stream = File.Open("ProfileData.bin", FileMode.Create))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter .Serialize(stream, usersList);
}
}
catch { }
One thing to note is that WPF wants us to use the ObservableCollection<T> class when displaying data in the UI, but this class causes problems when serializing data with this method... therefore, you will need to convert your ObservableCollection<T> to a List<T> or similar. However, this can be easily achieved:
List<User> usersList = users.ToList();
You can find out how to de-serialize your data from the C# Serialize List tutorial. You would deserialize (or load the data from the saved file) each time your application starts and re-save the file each time the program closes. You can add an event handler to the Application.Deactivated Event or the Window.Closing which gets called when the application closes, so you can put your code to save the file in there.
Well, I took longer and wrote more than I had expected, so I hope that helps.

Silverlight, update gui by changing img source c#

I'm trying to make a binary clock, an it works fine.
It works like this.
Every time you call a method called run, it sets the time, and change some img source (the img is my lamp, change img source every time it shut off or on).
But how can I get it to run all the time?
If I make a loop it won't start on my mobile, and it's like using threading does do anything.
Is there a method for update the gui after you change some properties?
XMAL Code
<phone:PhoneApplicationPage
x:Class="BinSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Height="80" HorizontalAlignment="Left" Margin="141,187,0,0" Name="imag1" Stretch="Fill" VerticalAlignment="Top" Width="106" Source="/BinSample;component/img/knapSluk.png" />
</Grid>
</Grid>
public MainPage()
{
InitializeComponent();
//test one
//try to make a neverending loop
Run();
//testc two
//try loop with thread an sleep funtion.
thredRun();
}
public void thredRun()
{
new Thread(new ThreadStart(thredRun));
while (true)
{
Run();
Thread.Sleep(100);
}
}
public void Run()
{
while (true)
{
int hour = DateTime.Now.Hour;
if (hour % 10 == 0)
imag1.Source = new BitmapImage(new Uri("img/knapTaand.png", UriKind.Relative));
else
imag1.Source = new BitmapImage(new Uri("img/knapSluk.png", UriKind.Relative));
}
}
}
There are a few problems here.
First you are not using the Thread class correctly, check this tutorial to get started
Even when you do correct your usage of the Thread class, you are either going to end up blocking the UI Thread, or you will end up with a Cross-Thread exception.
In this case, perhaps the easiest way for you to achieve what you want is to use a DispatcherTimer
public MainPage()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromHours(1) };
timer.Tick += new EventHandler(timer_Tick);
SetImageSource();
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
SetImageSource();
}
void SetImageSource()
{
int hour = DateTime.Now.Hour;
if (hour % 10 == 0)
imag1.Source = new BitmapImage(new Uri("img/knapTaand.png", UriKind.Relative));
else
imag1.Source = new BitmapImage(new Uri("img/knapSluk.png", UriKind.Relative));
}

Categories

Resources