C# create JSON from TextBox and monthCalendar - c#

Now I have a WindowsForm with a textbox and a calendar, and two buttons (continue and finish).
The user has to enter a Text to the box and select a date.
If he presses continue, the text and the date have to be written to a json file.
Then, the same window should open again and he can enter new values.
Finally, if he`s clicking the finish button, the Values should be written to the file and the window can close.
(User should click finish already after he entered the first value).
I already created a get/set class:
class Nachrichten_Felder
{
public string Nachrichten { get; set; }
public string Datum { get; set; }
}
How can I achieve this job? I really don`t know how to write the text and date to the json and reopen the window again...
For C# I use JSON.NET.

Ok, I made homework for you.
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
//InitializeComponent();
var newsButton = new Button { Parent = this, Text = "Show" };
newsButton.Click += NewsButton_Click;
}
private void NewsButton_Click(object sender, EventArgs e)
{
DialogResult result;
do
{
using (var newsForm = new NewsForm())
result = newsForm.ShowDialog();
} while (result == DialogResult.OK);
}
}
class NewsForm : Form
{
TextBox newsTextBox;
MonthCalendar monthCalendar;
Button continueButton;
Button finishButton;
Nachrichten_Felder news;
public NewsForm()
{
Width = 400;
newsTextBox = new TextBox { Parent = this, Multiline = true, Size = new Size(200, 200) };
monthCalendar = new MonthCalendar { Parent = this, Location = new Point(220, 0), MaxSelectionCount = 1 };
continueButton = new Button { Parent = this, Text = "Continue", Location = new Point(200, 220), DialogResult = DialogResult.OK };
finishButton = new Button { Parent = this, Text = "Finish", Location = new Point(300, 220), DialogResult = DialogResult.Cancel };
news = new Nachrichten_Felder();
newsTextBox.DataBindings.Add("Text", news, "Nachrichten");
monthCalendar.DataBindings.Add("SelectionStart", news, "Datum");
this.FormClosing += NewsForm_FormClosing;
}
private void NewsForm_FormClosing(object sender, FormClosingEventArgs e)
{
string json = JsonConvert.SerializeObject(news, Formatting.Indented);
File.AppendAllText(#"news.txt", json);
}
}
class Nachrichten_Felder
{
public string Nachrichten { get; set; }
public DateTime Datum { get; set; }
}
}

Related

How to add radio button option to as a class attribute to show in new WPF window?

I am new to C#, and am trying to create a basic project in which the user enters Client details (name, phone, email) and selects their location by a radio button as one out of three locations.
The locations are radio buttons within the menu item, 'MenuLocClient'.
Then the user clicks 'Add Client' to see the Client's name to appear in the list box,'LstClients'.
When the client name is selected from the list box, and the user clicks 'Show Client' the window, Client details is brought up with the client information (name, phone, email, location) like so:
I have my client class defined as:
namespace WpfApp_project
{
public partial class Client
{
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Location { get; }
public Client(string n, string p, string e, string l)
{
Name = n;
Phone = p;
Email = e;
Location = l;
}
}
}
In my ClientDetails window:
public partial class ClientDetails : Window
{
public ClientDetails(Client c)
{
InitializeComponent();
LblNameClient.Content = c.Name;
lblPhoneClient.Content = c.Phone;
lblEmailClient.Content = c.Email;
blLocClient.Content = c.Location;
}
}
In my main Window:
public partial class MainWindow : Window
{
// My client list
List<Client> ClientList = new List<Client>();
public MainWindow()
{
InitializeComponent();
}
// method to select location via radio button. it would be something like this?
public void radio_selected(…)
{
string selected;
if (RBLocE.isChecked) { selected = “Edinburgh”};
else if (RBLocG.isChecked) { selected = “Glasgow”};
else if (RBLocO.isChecked) { selected = “Other”};
Client c = …
c.Location = selected;
}
// method to create a new client on click
private void newClient(object sender, RoutedEventArgs e)
{
Client c = new Client(boxClientName.Text, boxClientPhone.Text, boxClientEmail.Text, ...); # add selected for location?
BoxClientName.Clear();
boxClientPhone.Clear();
boxClientEmail.Clear();
#rb.Checked = false;?
ClientList.Add(c);
lstClients.ItemsSource = null;
lstClients.ItemsSource = ClientList;
}
// method to show details of selected client
private void showDetails(object sender, RoutedEventArgs e)
{
Client c = lstClients.SelectedItem as Client;
if (c != null)
{
ClientDetails w = new ClientDetails(c);
w.Show();
}
}
Can someone please help me how to define my methods in MainWindow to add Location as selected by a radio button?
There are many ways to do this. Normally I would bind to an enum with a value converter as shown in this answer.
However as you are not using binding at all I'm going to assume you are at an earlier stage of learning and this can be done with a simple if/else in code behind. In fact you mostly already did this in your radio_selected method, you just need to modify it slightly to return the value.
public string GetSelectedLocation()
{
string selected = string.Empty;
if (RBLocE.isChecked) { selected = “Edinburgh”};
else if (RBLocG.isChecked) { selected = “Glasgow”};
else if (RBLocO.isChecked) { selected = “Other”};
return selected;
}
Then when creating your new client:
Client c = new Client(boxClientName.Text, boxClientPhone.Text,
boxClientEmail.Text, GetSelectedLocation());

How to show a spelling error suggestions popup on mouse over a WPF TextBox with spell checking enabled in Winforms C#?

I am using element host to use WPF spell checker textbox in my winforms.
I want to override the context menu that appears on misspelled red squiggles to mouse hover instead of right click.
How to do that?
Tried overriding the behavior but it is still the same:
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Forms.Design;
[Designer(typeof(ControlDesigner))]
class SpellCheck: ElementHost
{
privated TextBox box;
public SpellCheck()
{
box = new TextBox();
base.Child = box;
box.TextChanged += (s, e) => OnTextChanged(EventArgs.Empty);
box.SpellCheck.IsEnabled = true;
box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
}
[DefaultValue(false)]
public bool Multiline
{
//checks for multiline
}
public bool IsEnabled
{
//checks for spell check enabled or not
}
[DefaultValue(false)]
public bool WordWrap
{
//does wordwraps
}
[DefaultValue(false)]
public int MaxLength
{
//maxlength property
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new System.Windows.UIElement Child
{
get { return base.Child; }
set { }
}
}
It shows spell suggestions on right click. I want to change it to Mouse hover or any other mouse events.
You could use TextBox.PreviewMouseMove to show a popup to achieve this.
You also need to create a new Form to serve as a popup. This Form could contain a FlowLayoutPanel to host the suggestions. In this example the Form is named CustomPopup:
box.PreviewMouseMove += OpenContextMenuOnMouseMove;
The event handler for TextBox.PreviewMouseMove:
private void OpenContextMenuOnMouseMove(object sender, System.Windows.Input.MouseEventArgs mouseEventArgs)
{
var textBox = sender as System.Windows.Controls.TextBox;
var mouseOverTextIndex = textBox.GetCharacterIndexFromPoint(mouseEventArgs.GetPosition(textBox), false);
// Pointer is not over text
if (mouseOverTextIndex.Equals(-1))
{
return;
}
int spellingErrorIndex = textBox.GetNextSpellingErrorCharacterIndex(mouseOverTextIndex, LogicalDirection.Forward);
// No spelling errors
if (spellingErrorIndex.Equals(-1))
{
return;
}
int startOfWordIndex = mouseOverTextIndex;
while (startOfWordIndex != -1 && !textBox.Text[startOfWordIndex].Equals(' '))
{
startOfWordIndex--;
}
var endOfWordIndex = textBox.Text.IndexOf(" ", mouseOverTextIndex, StringComparison.OrdinalIgnoreCase);
if (endOfWordIndex.Equals(-1))
{
endOfWordIndex = textBox.Text.Length - 1;
}
// Spelling error doesn't belong to current mouse over word
if (spellingErrorIndex < startOfWordIndex || spellingErrorIndex > endOfWordIndex)
{
return;
}
using(CustomPopup popup = new CustomPopup())
{
// Create clickable suggestions for the CustomPopup.
foreach (var suggestion in textBox.GetSpellingError(spellingErrorIndex).Suggestions)
{
// Each Button represents a suggestion.
var suggestionButton = new System.Windows.Forms.Button() { Text = suggestion };
var fixSpellingErrorEventArgs = new FixSpellingErrorEventArgs()
{
TargetTextBox = textBox,
WordStartIndex = startOfWordIndex,
WordEndIndex = endOfWordIndex,
Suggestion = suggestion
};
// The Button.Click callback will apply the selected fix
suggestionButton.Click += (s, e) => FixSpellingError_OnButtonClicked(fixSpellingErrorEventArgs);
// TODO::Replace the line with a public member of CustomPopup Form: CustomPopup.AddPanelContent(Control):void.
// e.g. public void AddPanelContent(Control control) { this.FlowLayoutPanel1.Controls.Add(suggestionButton); }
// and use it like: popup.AddPanelContent(suggestionButton);
popup.FlowLayoutPanel1.Controls.Add(suggestionButton);
}
popup.SetDesktopLocation((int) mouseEventArgs.GetPosition(textBox).X, (int) mouseEventArgs.GetPosition(textBox).Y);
popup.ShowDialog(this);
}
}
// The event handler that applies the selected fix.
// Invoked on popup button clicked.
private void FixSpellingError_OnButtonClicked(FixSpellingErrorEventArgs e)
{
// Select misspelled word and replace it with the selected fix
e.TargetTextBox.SelectionStart = e.WordStartIndex;
e.TargetTextBox.SelectionLength = e.WordEndIndex - e.WordStartIndex;
e.TargetTextBox.SelectedText = e.Suggestion;
}
The custom event arg object for Button.Click event
class FixSpellingErrorEventArgs : EventArgs
{
public System.Windows.Controls.TextBox TargetTextBox { get; set; }
public int WordStartIndex { get; set; }
public int WordEndIndex { get; set; }
public string Suggestion { get; set; }
}
To enhance the example create the logic how or when the popup will disappear (time out and focus lost?).

How to change a xaml button property using it's string name from c# in UWP?

Relative noob here coming from Python trying to build a UWP app in c# and XAML.
The short version: How do I refer to a button using its string 'Name' to change its color. It seems that if I have given it a name I should be able to refer to it by its name, something like:
"navBtn5".Background = myColor;
//or
navBtn5.Background = myColor;
I have looked all over, the best I found was this from here on stackOverflow:
How to control a xaml button from C# in WPF
which looks exactly like what I want. However this does not work, will not even build as I just get told:
Error CS0103 The name 'navBtn5' does not exist in the current context
This could be because I am using UWP and that is for WPF.
The long Version: My app is creating the navigation menu by data binding to a List that is put together in a separate class. I am creating a type of MenuButton in my class then returning a list of them. This is a stripped down version of my class:
class MenuButton{
public string buttonName { get; set; }
public string buttonContentText { get; set; }
public int buttonWidth { get; set; }
public int buttonHeight { get; set; }
public List<byte> buttonColor { get; set; }
}
class menuButtonManager{
public static List<MenuButton> getButtons(){
var menuButtons = new List<MenuButton>();
menuButtons.Add(new MenuButton{
buttonName = "navBtn1",
buttonWidth = 50,
buttonHeight = 50,
buttonContentText = "\uE173",
buttonColor = new List<byte> { 255, 82, 190, 128 },
});
menuButtons.Add(new MenuButton{
buttonName = "navBtn2",
//and so on
});
menuButtons.Add(new MenuButton{
//and so on
});
}
return menuButtons;
}
At Run Time, when the user clicks a button I want to loop through all the buttons in the List and change their color to grey if it was not that one that was clicked, green if it was the clicked button. something like this:
private void navClick(object sender, RoutedEventArgs e){
//who called me
string senderName = ((Button)sender).Name;
foreach(MenuButton m in menuButtons){
if(m.buttonName == senderName){
Button senderButton = (Button)sender;
senderButton.Background = myFunkyColor;
// I can already do this as I already have
// the sender cast to a button
}
else{
// change button to grey
// This is where I am stuck
// I know m.buttonName as a string
// how do I create a usable button object from it?
}
}
}
As you can see I have no trouble changing the properties of the button that was the sender as I have cast it to a type of Button which I can use. The problem for me is when I am acting on a button that is not the sender and all I have is it's string name.
You do not have to create a new class if you are using default properties(Unless it is your requirement).
Make your List of Buttons Global
List< Button> menuButtons = new List< Button>();
public static List<Button> getButtons()
{
for ( int i=0; i<5; i++)
{
Button _button = new Button
{
Name = "navBtn" + i.ToString(),
Width = 50,
Height = 50,
Content = "\uE173",
Background = new SolidColorBrush(Colors.Gray)
};
_button.Click += _button_Click;
menuButtons.Add(_button);
}
return menuButtons;
}
The above will return 5 new buttons( something like your requirement ). Look at
_button.Click += _button_Click;
An event for click will be explicitly created for each button in the list.
private static void _button_Click(object sender, RoutedEventArgs e)
{
Button Clicked = (Button)sender;
foreach(Button btn in menuButtons)
{
if (Clicked.Name == btn.Name)
{
btn.Background = myFunkyColour;
}
else
{
btn.Background = //Your Disabled Colour.
}
}
}
Click event will return you the button that was clicked.
Hope this helps.

Data from form1 listbox to form2 textbox

The goal of the program assignment I'm working on requires me to fill a listbox with items taken from a data file, and then allowing the user to modify parts of the selected item. To do this, I need assistance in figuring out how to pass part of a listbox's selected item in one form to a textbox in another form.
Here's the coding I have for the first form in my program:
public partial class Form1 : Form
{
const char DELIM = '\\';
const string FILENAME = #"C:\Visual Studio 2015\Data Files\Training Workshops data";
string recordIn;
string[] Fields;
static FileStream file = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(file);
public int X;
public Form1()
{
InitializeComponent();
}
public class Workshop
{
public string title { get; set; }
public int days { get; set; }
public string categrory { get; set; }
public double cost { get; set; }
public string[] categrorynames =
{
"Application Development",
"Databases",
"Networking",
"System Administration"
};
}
Workshop shop = new Workshop();
private void button1_Click(object sender, EventArgs e)
{
Form2 secondForm = new Form2();
secondForm.Show();
}
private void PopulateList(string filePath)
{
while(recordIn != null)
{
try
{
recordIn = reader.ReadLine();
Fields = recordIn.Split(DELIM);
X = Convert.ToInt32(Fields[0]);
shop.categrory = shop.categrorynames[X];
shop.days = Convert.ToInt32(Fields[1]);
shop.title = Fields[3];
shop.cost = Convert.ToDouble(Fields[2]);
}
catch (Exception A)
{
if (X < 0 && X > 3)
{
shop.categrory = "invalid";
}
if (shop.days != Convert.ToInt32(Fields[1]))
{
shop.days = 0;
}
if (shop.title != Fields[3])
{
shop.title = "invalid";
}
if (shop.cost != Convert.ToDouble(Fields[2]))
{
shop.cost = 0;
}
}
}
}
}
And below is a link to a screenshot of the second form:
http://i.stack.imgur.com/IRqVh.png
I need to transfer the shop.categrory data of form1's listbox's selected item to the second form's, and the shop.title, shop.days and shop.cost to the corresponding textbox's. From there I can make it so that whatever the user enters in the textboxes would change the data of the selected item when they press the "save and exit" button.
Any help would be appreciated, and if anyone notices an error in the coding I have now, please feel free to point them out.
Create a Parameterized constructor in form2 that accepts a String, and create it's instance in first form, and pass the value you want to pass to the second form:
private void button1_Click(object sender, EventArgs e)
{
Form2 secondForm = new Form2("DATA TO BE SENT");
secondForm.Show();
}
and in form2 Create a Constructor:
public Form2(string data)
{
InitializeComponent();
txtData.Text=data;
}

C# property grid string editor

What is the easiest way to have Visual Studio-like editor for string in PropertyGrid? For example in Autos/Locals/Watches you can preview/edit string values in-line but you can also click on magnifying glass and see string in external window.
You can do this via a UITypeEditor, as below. Here I'm using it on an individual property, but IIRC you can also subvert all strings (so that you don't need to decorate all the properties):
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using(var frm = new Form { Controls = { new PropertyGrid {
Dock = DockStyle.Fill, SelectedObject = new Foo { Bar = "abc"}}}})
{
Application.Run(frm);
}
}
}
class Foo
{
[Editor(typeof(FancyStringEditor), typeof(UITypeEditor))]
public string Bar { get; set; }
}
class FancyStringEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (svc != null)
{
using (var frm = new Form { Text = "Your editor here"})
using (var txt = new TextBox { Text = (string)value, Dock = DockStyle.Fill, Multiline = true })
using (var ok = new Button { Text = "OK", Dock = DockStyle.Bottom })
{
frm.Controls.Add(txt);
frm.Controls.Add(ok);
frm.AcceptButton = ok;
ok.DialogResult = DialogResult.OK;
if (svc.ShowDialog(frm) == DialogResult.OK)
{
value = txt.Text;
}
}
}
return value;
}
}
To apply this for all string members: instead of adding the [Editor(...)], apply the following somewhere early in the app:
TypeDescriptor.AddAttributes(typeof(string), new EditorAttribute(
typeof(FancyStringEditor), typeof(UITypeEditor)));

Categories

Resources