pass textbox string to custom control in wpf? - c#

Im using wpf and I want to pass a paramter of some textbox.text string on button click from my main window to my user control contained in my appPages folder, how can I achieve this?
The app control I want to send it to is called FindCurrentStudent, I dont like asking for direct code but I cant really find anything on this?
The way I was thinking was something like:
private void btnGeneral_Click(string _value, object sender, RoutedEventArgs e)
{
string value = textBox1.Text;
AppPages.FindCurrentStudent v1 = new AppPages.FindCurrentStudent(value);
//does not contain a constructor?
value = _value;
And then from the customcontrol I could call it like so:
string MainWindowValue = value;

There are various ways to achieve this. Depending on your current design, you might:
bind Button.Command to a command exposed by your UserControl, and Button.CommandParameter to the TextBox.Text
bind a property exposed by your UserControl to TextBox.Text
bind to properties on your view model(s)
You'll need to give more information on your current design before I could helpfully elaborate.

Related

Property in View must match identical property in ViewModel

I am creating a user control (a textbox that only accepts integers). The control has to have properties to specify max/min values and whether to allow negative values etc.). I am using MVVM, in my view I have public properties e.g.
const string EXAMPLE = "Example";
string example;
public string Example
{
get { return example; }
set
{
if (value == example) return;
example = value;
OnPropertyChanged(EXAMPLE);
}
}
These properties are in my View so that someone using the control will be able to easily set them. In my ViewModel I have an identical property, I need these properties to be bound together so that they and their backing fields always have the same value. I hate the code repetition too.
To be honest the whole approach feels wrong and usually that is a good indication that I am approaching the whole thing from the wrong direction or misunderstanding something fundamental.
I have used WPF before but this is a first attempt at a custom control.
The first thing I want to make sure is that you're truly trying to make a CustomControl and not a UserControl. I believe this question basically is the same as yours except worded differently.
A UserControl lends itself to the MVVM pattern way more readily than a CustomControl because you would have a .xaml (and .xaml.cs) file along with a .cs file to serve as the ViewModel. On the other hand, a CustomControl is never done with MVVM, as the visual appearance (view) is defined and overridable via a ControlTemplate.
Since you said you have a View and ViewModel, let's think about how you would achieve the behavior you want with your textbox. Your textbox will have to validate and reject user input outside the range of values you desire. This means your View code-behind has to have properties and logic that control the restrictions in the input values of the textbox defined in your View. You have already violated MVVM here.
When you said you have a View, that makes me think you're writing a UserControl. But your requirements (a custom behavior for textbox) suggest that you really need a CustomControl, for which you do not use MVVM.
If you agree that you need a CustomControl, here's a quick and dirty example:
public class RestrictedTextBox : TextBox
{
public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(int), typeof(RestrictedTextBox), new PropertyMetadata(int.MaxValue));
public RestrictedTextBox()
{
PreviewTextInput += RestrictedTextBox_PreviewTextInput;
}
public int MaxValue
{
get
{
return (int)GetValue(MaxValueProperty);
}
set
{
SetValue(MaxValueProperty, value);
}
}
private void RestrictedTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
int inputDigits;
RestrictedTextBox box = sender as RestrictedTextBox;
if (box != null)
{
if (!e.Text.All(Char.IsDigit))
{
// Stops the text from being handled
e.Handled = true;
}
else if (int.TryParse(box.Text + e.Text, out inputDigits))
{
if (inputDigits > MaxValue)
e.Handled = true;
}
}
}
}
XAML Usage:
<local:RestrictedTextBox MaxValue="100"></local:RestrictedTextBox>
There is no MVVM in a Custom Control.
Any Control is only in the View layer. So what you need to do is expose relevant DP to a consumer that you have no knowledge of.
In the Custom Control you need to define your Control behavior, how it reacts to change in DP value and what should be available to a consumer. In the default Template you define how you want to display this Control.
The consumer may want to set or get some dp values so he'll have to bind your Custom Control'dp to a property in his ViewModel but that's up to him.

Accessing controls from different forms

I have a main form with some buttons, textboxes, labels, etc.
On a second form I would like to copy the text from the main forms textbox onto the second form.
Have tried:
var form = new MainScreen();
TextBox tb= form.Controls["textboxMain"] as TextBox;
textboxSecond.Text = tb.Text;
But it just causes an exception. The main screen textbox is initialised and contains text.
When I hover over form I can see all the controls are there.
What am I doing wrong?
Looking at the original code, there are two potential reasons for the NullReferenceException you are getting. First, tb is not defined in the code you provide so I am not sure what that is.
Secondly, TextBox textbox = form.Controls["textboxMain"] as TextBox can return null if the control is not found or is not a TextBox. Controls, by default, are marked with the private accessor, which leads me to suspect that form.Controls[...] will return null for private members.
While marking the controls as internal will potentially fix this issue, it's really not the best way to tackle this situation and will only lead to poor coding habits in the future. private accessors on controls are perfectly fine.
A better way to share the data between the forms would be with public properties. For example, let's say you have a TextBox on your main screen called usernameTextBox and want to expose it publicly to other forms:
public string Username
{
get { return usernameTextBox.Text; }
set { usernameTextBox.Text = value; }
}
Then all you would have to do in your code is:
var form = new MainForm();
myTextBox.Text = form.Username; // Get the username TextBox value
form.Username = myTextBox.Text; // Set the username TextBox value
The great part about this solution is that you have better control of how data is stored via properties. Your get and set actions can contain logic, set multiple values, perform validation, and various other functionality.
If you are using WPF I would recommend looking up the MVVM pattern as it allows you to do similar with object states.
PhoenixReborn is correct. The problem is that you are creating a new MainScreen, which means that new controls are created, so unless the text in your controls are initialized in the form constructor, they are going to be empty. Usually, the way to handle this is to pass the first form instance to the second form, like this:
SecondForm second = new SecondForm(this);
and in the second form:
public SecondForm (MainForm form)
{
// do something with form, like save it to a property or access it's controls
}
That way, the second form will have access to the first form's controls. You might consider making the properties you need to use public (in the designer properties pane). That way you can just do form.textboxMain.Text.

custom windows form properties

I have created a customize windows form and I just don't know how should I set properties to it.
for example I've created a form with a progress bar, button, and a label and want to set the text of the label, the value of the progress bar, and to get access to the buttonClick Event method form the windows form application that uses the control.
In other words just get access to all the default properties of each control inside.
Is it possible? and how should I do it?
thanks very much!
If I want to to get access to the buttonClick Event method how should I do it?
You need to cast from Control to the type of your custom control before you can access the properties you have defined.
var myCtrl = (MyControl)controlRef;
myCtrl.MyProperty = xxxx;
This code assumes that MyProperty has been declared as public.
If I understand your question correctly, you want to expose controls on a form to outside code.
One way to achieve this would be to declare accessible properties on the form, for example:
public ProgressBar MyProgressBar
{
get { return progressBar1; }
}
If you wish to only expose certain properties of the controls, you could also have properties that access these directly, like so:
public int MyProgressBarValue
{
get { return progressBar1.Value; }
set { progressBar1.Value = value; }
}

How to access UserConrtorl's controls in this situation

I have an UpdatePanel.
and I have a PlaceHolder inside this UpdatePanel.
There is a number of UserControls. One of them will be loaded dynamically,
according to some selections.
Control mycontrol = this.Page.LoadControl("myusercontrol.ascx");
myplaceholder.Controls.Add(mycontrol);
after loading a specific UserControl, I wanted to get the text written in
a TextBox that is in the loaded UserControl from the Parent page.
TextBox mytextbox = (TextBox) Page.FindControl("myusercontrol")
.FindControl("mytextbox");
The problem was the text is always empty !
What am I missing ?
I appreciate your help.
You should load your UserControl overriding OnInit as mentioned before. And why were you looking entire page to find the UserControl? You can use PlaceHolder.Controls...
This how I got it work
protected override void OnInit(EventArgs e)
{
Control userControl = this.Page.LoadControl("WebUserControl.ascx");
testPlaceHolder.Controls.Add(userControl);
userControl.ID="id";
base.OnInit(e);
}
protected void testButton_Click(object sender, EventArgs e)
{
Control testUserControl = (Control)testPlaceHolder.Controls[0];
//Control testUserControl=(Control)testPlaceHolder.FindControl("id");
TextBox mytextbox = (TextBox)testUserControl.FindControl("testTextBox");
testButton.Text = mytextbox.Text;
}
When you say that the text is always empty, do mean the TextBox object is null or literally the .Text of the textbox is empty?
Remember that in web applications you have to post back to the server to refresh results and update controls among other things.
Try posting back to the server and seeing if that helps.
Have you considered adding a property to your user control to return the text?
eg:
public class YourControl : UserControl
{
public string Text
{
get
{
return this.TextBox1.Text;
}
}
}
Usually, User Controls are used for encapsulation - you wrap up all the details of controls, behaviour etc in a UC so other code doesn't have to deal with it.
By referring to controls within the UC directly - by name or ID - you're breaking the model. Can I suggest you don't do this, instead if you need to get information from the UC you add a property, event or method to it that the container can call.
That way if you need to change the UC - control names, types, styles, or additional logic is used later - you only need to change that property/event/method in the UC, not in the (for example) 100 places it might be used in the code.
If you could let us know why you need this information or more specific details about the example, perhaps we can suggest some code to implement this.
So, what should I do ?
Just get the posted values manually.
Request.Form[yourcondeol.UniqueID]
by debugging this you can see all the posted data.
Request.Form

rename control in wpf using c#

if I add control in Microsoft Blend 4 without set Name to this control and I want to set name to it and use it in c# how ?
example I added button using Blend in my layout but without give it a name
I want to give it a name using c# without x:Name="" in xaml
In your place I would give LogicalTreeHelper.GetChildren (this) a chance. It returns a collection of children to Window (this is a handle to Window) Reference MSDN
From there you can try to find your control.
But I think it is easier to try to rewrite the control (or look for another component) so you can have names on the children. That was your problem from the start.
Hope it helps
Gorgen
First, why in the world would you want to do that?
If you do not set a name you have no easy way of accessing the control. However you can get access to the control via relationships to other controls or events that pass a reference, for example the loaded event.
e.g.
private void Menu_Loaded(object sender, RoutedEventArgs e)
{
(sender as Menu).Name = "MainMenu";
}
Or if the control is the child of another control:
(ControlStack.Children[0] as Menu).Name = "MainMenu";
But i cannot think of anything useful that could be achieved by that...
You probably just want to get a reference to the object which you can easily store in a class member. In some cases you can also slice up your XAML using resources.
e.g.
<local:SomethingIWouldLikeToReference x:Key="SomethingIWouldLikeToReference"/>
<local:UserControl x:Name="userControl">
<Stuff>
<MoreStuff Content="{StaticResource SomethingIWouldLikeToReference}"/>
</Stuff>
</local:UserControl>
public MainWindow()
{
InitializeComponent();
MyReference = FindResource("SomethingIWouldLikeToReference") as SomethingIWouldLikeToReference;
}
Example if I have ListView Control and I want to use it to add items and remove items
Make private ListView and initialize it
ListView temp_control_List = new ListView()
then make loaded Eventhandler from Blend so it will be in VS then
private void ListView_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
temp_control_List = sender as ListView;
}
Now you can add and remove to and from the list view control from temp_control_List

Categories