0

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.

You begin the form by entering the information. enter image description here enter image description here enter image description here

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();
    }
}
}
1
  • 4
    You don't save the button. You save some information you need and you show / generate buttons according to that information. How you save the information is up to you: serialization (binary, xml, json,...), plain text, registry, etc. Commented Aug 29, 2013 at 4:47

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.