How to implement template control for dynamically add controls in wpf? - c#

I have page with some control like picture. i want to add these control dynamically and when user click add those control add dynamically. how can i implement this? i want to use template control or something like this.

Why don't you take "sample label, persian translate label, textboxes and add voice button" and put them in a usercontrol (Let's give it the name MyUserControl)
then instead of adding that user control directly on the grid of your window, add a stack panel (lets name it MyStackPanel), and add that user control into the stack panel (stack panel must have the orientation set to vertical)
Now when the user clicks on the "Plus" button your code will be:
MyStackPanel.Children.Add(new MyUserControl() { Margin = new Thickness(0, 5, 0, 0) });
This will give you the same controls you asked for with a margin top = 5.
You will only write code once for the user control, and all the added controls (after clicking on the plus button) will have the same code.
Edit:
If you want to delete MyUserControl when clicking the delete button add the following code for for the StackPanel (MyStackPanel) on the main window (look for ButtonBase.Click):
<StackPanel Height="236" HorizontalAlignment="Left" ButtonBase.Click="stackPanel1_Click" Name="stackPanel1" VerticalAlignment="Top" Width="491">
and for the event of the StackPanel:
private void stackPanel1_Click(object sender, RoutedEventArgs e)
{
if (((UserControl1)e.Source).Tag.ToString() == "1")
{
stackPanel1.Children.Remove(((UserControl1)e.Source));
}
else
{
MessageBox.Show("Another button was clicked");
}
}
Now the delete button on the user control must have the following line of code:
this.Tag = 1;

According to me using Implicit Data Templates is much easier then anything else User Control also a Good Choice but Data Templates OR Implicit Data Templates are much better.
Take a Look Data Templates

Related

How to show an ErrorProvider error icon next to a TabPage header?

Edit:
This is not a duplicate of Icons in TabControl C# - How?. The question there is about adding icons to tab pages. Here it is about how the change the error provider error icon position to be inside the header instead of to the right of the tab page itself. Also, the error provider error icon has the functionality that when you hover the mouse on it, you see the error text, which you do not see if you simply add an icon to the header.
I have a form with a TabControl. The form has also an ErrorProvider. When I try to use the following code:
errorProvider1.SetError(tabPage1, "error");
The error icon is shown to the right of the tab page, and it is cut-off by the tab control itself:
I would like the icon to be shown next to the tab page header. Something like this (made with Photoshop):
I do not know where to start, or how to approach this.
Edit:
I have a class responsible for adding errors to a control, and showing them using an error provider. This class is used for TextBoxes, NumericUpDowns etc. I would like to use it also for TabPages. The problem is that when I use it for tab pages I get the result shown above. The trick of adding an error icon to the header using an ImageList and then add a tooltip is not good, because it is specific to tab pages, and I cannot implement it in my class which is general to all controls. So I really need to change the settings of the tab page so when I use errorProvider.SetError(...) it is shown in the header.
ErrorProvider shows error icon of the TabPage in tab page's client area.
By playing with IconAlignment or IconPadding, you can show error icon of TabControl on one of the tab pages' headers, but it's error icon for the whole TabControl.
In a real application each of the tab pages can contain controls which are not valid and you may want to show the validation icon on tab pages not for the tab control.
My suggestion is using tab page icon by setting ImageList containing the error icon as image list of the TabControl and by setting ImageIndex of the TabPage, show or hide the image icon. This way you can show the error icon for every tab page which needs it:
Example
To setup the example, follow these steps:
Create a Form.
Drop a TabControl, an ErrorProvider and an ImageList on the Form.
Set ImageList property of tabControl1 to imageList1.
Drop two TextBox on tabPage1.
I assume, just for example, you are going to validate these two text box controls using Validating event. The key point is here. When you validate any control, check if it's hosted in a TabPage, check validity of all children of TabPage and set the error icon based on that:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.AutoValidate = AutoValidate.EnableAllowFocusChange;
imageList1.ColorDepth = ColorDepth.Depth32Bit;
imageList1.Images.Add(errorProvider1.Icon);
tabControl1.ImageList = imageList1;
textBox1.Validating += textBox_Validating;
textBox2.Validating += textBox_Validating;
}
private void textBox_Validating(object sender, CancelEventArgs e)
{
var textBox = (TextBox)sender;
if (string.IsNullOrEmpty(textBox.Text))
{
this.errorProvider1.SetError(textBox, "Value is required.");
e.Cancel = true;
}
else
this.errorProvider1.SetError(textBox, null);
var tabPage = textBox.Parent as TabPage;
if (tabPage != null)
ValidateTabPage(tabPage);
}
void ValidateTabPage(TabPage tabPage)
{
var tabIsValid = tabPage.Controls.Cast<Control>()
.All(x => string.IsNullOrEmpty(errorProvider1.GetError(x)));
if (tabIsValid)
tabPage.ImageIndex = -1;
else
tabPage.ImageIndex = 0;
}
You can do the following.
Rectangle rc = tabControl1.GetTabRect(0); // Replace with the index of Tab required
errorProvider1.SetIconPadding(tabControl1, -rc.Left-20);;
errorProvider1.SetError(tabControl1, "Error String");
You also need to set
errorProvider1.SetIconAlignment(tabControl1, ErrorIconAlignment.TopLeft);
Sample (With Second Tab Selected - based on comments),
You would need to prepend whitespace to your TabPage Text to ensure there is sufficient space for showing the icon
With Icon on Second Tab

WPF application in one window

I am new in WPF and want to create WPF application like cookbook. I already done this and app work correctly. But I make it in this way:
First screen show buttons, which open new windows to do something. As a result i have 14 different windows. It is ok, but now i want to make it in other way.
I am trying to make one window, which will be showed at start, and change content. I divided window on two grids. First is static and is placed on bottom. It contains buttons, which represents functionality of the program. Second one will be dynamic. There i want to show content of every window. So i want to change content of this panel instead of creating new windows.
I tried to make *.cs files which will create controls in code-behind, functions and data. But my idea is not succesful and i do not know how to do this.
At all, I want to create app, which will work like this:
- if you click button "Add receip" then app will show controls to add name, ingredients and save it at the end.
- if you clik "Show receip" previous content will be replaced by list of ingredients
and etc.
I hope you will understand me.
You can create a Frame instead of second grid. Frame allows you to show pages, and not in seperate windows, in Frame itself. You can navigate the frame into the page like
mainFrame.Source = new Uri("Page1.xaml",UriKind.Relative);
This changes the frame to your page. You can change the source again, if you wanna change the page again.
Note: You can add tags to your buttons like "showReceip" and you can make just one buttonclick event for your buttons. Code will look like this.
mainFrame.Source = new Uri((sender as Button).Tag.ToString() + ".xaml",UriKind.Relative);
That takes the tag of your clicked button, add the string ".xaml" on it and take it on the source part. So, if your tag is "Page1", Source will look like "Page1.xaml" as my solution.
Appreciate the try, I hope you are looking for WPF user controls instead for separate windows. User controls are similar to windows you can create the UI and functionalities in the user control. I would like to recommend you to design the main window like the following:
<Grid>
<Canvas Name="canFunctionalButtons">
<!--Define the buttons inside this canvas
And allocate proper place for this in the UI
-->
</Canvas>
<Canvas Name="canControlContainer">
<!--This is to display the user control
Which can be changed dynamically according to the Button's click
-->
</Canvas>
</Grid>
Then you have to add click event for those buttons, which will add specific user control to the canControlContainer canvas. An example for adding an user control to this canvas is as follows, Let btnAddSomething be a button and btnAddSomething_Click be its click event then you can do something like:
private void btnAddSomething_Click(object sender, RoutedEventArgs e)
{
canControlContainer.Children.Clear(); // will remove previous contols from this canvas
// UC_AddSomething be the user control that you wanted to add here
canControlContainer.Children.Add(new UC_AddSomething());
}

How do I add a textblock dynamically to a page?

I'm just learning how to make universal apps for windows 10. Most of the tutorials show you how to work with XAML and how to assign functions to elements when you click on them but I couldn't find a way to make a new control appear when I click a button.
I'm making a note taking application. I've designed most of the stuff that I need. Now I want whenever I click a button to create a new textblock where the user can write their note.
//Create a new note when clicking the add button
private void newNoteBtn_Click(object sender, RoutedEventArgs e)
{
TextBox newNote = new TextBox();
newNote.Text = "Enter your text";
}
This is the code that runs when the button is clicked. When I run the application nothing happens. I think I have to put the new textbox in some kind of Grid or something.
Most of the tutorials are really old or mention windows forms and use some sort of this.Controls.Add(newNote); but Visual studio doesn't give me the Controls.Add option. I've also created a <Grid x:Name="notes"></Grid> which I thought I could use as a placeholder for the notes that are being created but I can't access the Grid element through the code.
Container Controls like Grid have Children property so you should use Childern like this:
TextBox newNote = new TextBox();
newNote.Text = "Enter your text";
notes.Childern.Add(newNote);
When defining
<Grid x:Name="notes"></Grid>
in XAML on the page, you be able to use notes as the identifier to access this Grid from the page's code behind:
notes.Children.Add(newNote);

Is it possible to add more than one panel in same location

i'm using telerik control.
So i want to ask,
In winforms application ,Is it possible to add more than one panel in same location and display one at a time just like show/hide property.
Make sure you have placed all panel control in same container or form. then you can use Visible property to show and hide panel. BringFront and SendToBack function will be used to bring panel on top or send it to back. If you have placed any panel in another panel then that will be disappeared when you Hide parent panel. So, Make sure all panels' parent control must be same. To determine the parent control simply select that panel and press escape key to select their parent.
private void LoadPanels()
{
panel1.Location = new Point(10,10);
panel2.Location = new Point(10,10);
panel3.Location = new Point(10,10);
panel4.Location = new Point(10,10);
panel5.Location = new Point(10,10);
VisiblePanel("panel1");
}
private void VisiblePanel(string panelName)
{
string[] panels = new string[]{"panel1","panel2","panel3","panel4","panel5"};
for (int i=0;i<panels.Length;i++)
this.Controls[panels[i]].Visible = (panels[i] == panelName);
this.Controls[panelName].BringToFront(); //Not required you can remove this line.
}
Here's a slightly different approach you might want to consider...
Are you wanting to be able to programmatically select the contents of a rectangular area at runtime, selecting among various controls to display? If so, you could use a custom TabControl which has its tabs (not the pages) hidden.
Then you can select which page is displayed by programmatically changing its SelectedIndex property at runtime.
Doing it like this means that your form editor will show a normal tab control, which allows you to much more easily add the content to each page - but at runtime the tabs will be hidden from the user; they will just see the contents of the currently selected page.
See Hans Passant's answer here for how to create such a custom tab control.
(However, you might also want to override the OnKeyDown for the custom tab control in order to ignore Ctrl-Tab.)

how can i achieve this in c#

i'm developing a windows form application.in the form, the left part is a tree menu, and the right part is show area. how can i change the show area according to what i click on the tree menu.
(source: 126.net)
i use treenode class to implement treemenu like this:
System.Windows.Forms.TreeNode treeNode27 = new System.Windows.Forms.TreeNode("basic operation");
what i try to do is use several panels. each panel bounds to a menu item. by setting the visible property, i can achieve that goal. but it is too inconvenient.especially when i try to design each panel.
any good suggestion?
You could design each "Panel" as a new User Control. That way you can design all of the "panels / areas" on their own, independently of the Main Form.
On your Main Form, create a single panel for the right hand side area and add all of the controls to that one panel.
Then when the TreeNode selection event happens you can set all the user controls to .Visible = false; except for the one you are showing and set that to .Visible = true; and .Dock = DockStyle.Fill;
What you need is an event handler that will be called at the time of the user clicking the treeview (Use TreeView from the toolBox). You can do that by selecting the treeview on the design page and under properties click on Events. Then select NodeMouseDoubleClick or NodeMouseClick depending upon what you want. Below is a code that captures the values selected...Enjoy...;)
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (treeView1.SelectedNode.Level == 2)
{
//text on the first level
string text = treeView1.SelectedNode.Text;
}
else if (treeView1.SelectedNode.Level == 1)
{
//text on the second level
string text = treeView1.SelectedNode.Text;
}
}

Categories