How To Get Text From Binded TextBlock Store App c# - c#

I want to get text from below TextBlock but i can't get it ??
Note : fname is property for setting text in TextBlock
<TextBlock Name="getname" Text="{Binding Path=fname }"/>

By default, the text binding for a TextBlock is One-Way. You'll need to explicitly specify a Two-Way binding if you want to read the value back into your view model.
Text="{Binding Path=fname, Mode=TwoWay}"
If you're not using view models and you just want programmatic access to the text value you'll need to access the value in code-behind.
public string GetTextBlockText()
{
return this.getname.Text;
}

Related

Binding a TextBlock 's Text property to current existing DataContext

For a TextBlock control, I want the Text property to be depending on the current DataContext, and I will display some very nice formatted string-- depending on the type of the DataContext-- with an IValueConverter to properly convert the Text property.
How to do this?
A Binding without a Path (or with Path=.) binds directly to the object in the DataContext of the the TextBlock:
<TextBlock Text="{Binding Converter={StaticResource ...}}" />

UWP TextBox.Text binding not updating when using PlaceholderText

I've got some text boxes for which i wanted to set the PlaceholderText property. The text of each box is bound to a property of the underlying view model. Now when setting the placeholder in the XAML like that
<TextBox PlaceholderText="Placeholder" Text={Binding PropertyName} />
i noticed, that the view model's properties are not updated anymore when the text box loses focus.
Whereas without placeholder the binding works just fine.
Is this behaviour intended and if are there any workarounds, or do i have to stick to a classic TextBlock that describes the intended input each box?
Edit: The property does implement INotifyPropertyChanged and the binding is updated in the view model when no placeholder is set.
PlaceholderText for TextBox does not change the TextBox behavior when it loses focus.
You can try explicitly using the "TwoWay" binding mode for the Text property, instead of the "Default" binding mode.
<TextBox PlaceholderText="Placeholder" Text="{x:Bind PropertyName, Mode=TwoWay}" />
Make sure your View's DataContext is set to your viewmodel, something like below
public MainPage()
{
this.DataContext = new MainViewModel();
this.InitializeComponent();
}
For more information on Binding mode, see to
https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx

TwoWay Binding Not Updating Target - Metro App

I'm building a Metro App using VS 2012 and the Windows 8 SDK. In the app, I have this class (with a corresponding struct)
// Parameter data structure for tools
public struct ToolParameter
{
public string Title { get; set; }
public Object Value { get; set; }
public string Description { get; set; }
}
// Tool that will be used to execute something on phone
public class Tool
{
public string Title{ get; set; }
public ObservableCollection<ToolParameter> Parameters { get; set; }
public string Description { get; set; }
}
On a certain page in the app, I bind an instance of the class to the dataContext of the page
this.DataContext = currentTool;
On the page, I display various information about the app, including the parameters, which I want to make editable on the page. Because of this, I'm using a TextBox to display the parameters so that it can be edited, and binding it to the "Value" member of the ToolParameter struct.
<TextBox x:Name="ParameterValue" FontSize="15" Text="{Binding Value, Mode=TwoWay}" TextWrapping="Wrap"/>
Unfortunately, when a TextBox is bound to a value, it doesn't update until it no longer has a focus, so I added a button that the user can click that will update the parameters (and change focus from the TextBox). Unfortunately, upon clicking of the button, though the focus changes, the values of the parameter in the currentTool variable is never changed. Is there something about data binding that I am missing? Might it be that the parent of the TextBox named ParameterValue (the parameters are all part of a ListView) has to be two way as well?
From what I can see, youre TextBox is binding to Value which is a property of the ToolParameter class. The DataContext for the page is of type Tool. Tool contains Parameters which is a collection of ToolParameter objects. So, the TextBox needs to be within an ItemsCollection that has the ItemsSource set to bind to the Parameters property.
Example:
<StackPanel>
<TextBlock Text="{Binding Title}"/>
<TextBlock Text="{Binding Description}"/>
<!-- showing a ListBox, but can be any ItemsControl -->
<ListBox ItemsSource="{Binding Parameters}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Value}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
Also make sure that your classes Tool and ToolParameter implement INotifyPropertyChanged and that the setter for your properties fire the PropertyChanged event
UPDATE: Adding info that was too large for a comment
This should help understand Source/Target in bindings. For your TextBox, the source of the binding is the Value property and the Target is the TextProperty of the TextBox. When the source updates, the Text will update within the TextBox. If you the TextProperty of the TextBox changes, then it will update the Value property of your object (provided mode is set to TwoWay). You're tool however will NOT update and neither will the Parameters property of the Tool class. If you wish to update the tool object when a property of a ToolParameter updates, then you will need to subscribe to the PropertyChanged event of each ToolParameter object that gets added to the Parameters collection.
Welcome to StackOverflow!
In the binding, you can specify the UpdateSourceTrigger to 'PropertyChanged':
<TextBox Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
The default value, which you are experiencing, is 'LostFocus'.

For a user control, how to set the binding of a item template item to a user property?

I have a simple user control, which is essentially just an AutoCompleteBox with some custom logic.
For a specific instance (a collection of Persons), I want it to look like this:
<sdk:AutoCompleteBox Name="myACB" ItemsSource="{Binding People}" FilterMode="StartsWith" MinimumPrefixLength="2" ValueMemberBinding={Binding LastName}>
<sdk:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding LastName}" />
</DataTemplate>
</sdk:AutoCompleteBox.ItemTemplate>
</sdk:AutoCompleteBox>
However, I want to make the data source generic and therefore the display values will be different (ValueMemberBinding and the template TextBlock text). That is why I am making a custom control so I can specify the differences with properties.
I have no problem setting the source with a user control property, but I am having difficulty with the display binding properties. Right now I have:
public static DependencyProperty DisplayMemberProperty = DependencyProperty.Register("DisplayMember", typeof(string), typeof(myAutoComplete), null);
public string DisplayMember
{
get
{ return myACB.ValueMemberPath; }
set
{
myACB.ValueMemberPath = value; // this works fine
// but how can set the text binding for the templated textblock?
}
}
I want the DisplayMember property to be the property name to display for whatever kind of custom collection (persons, cars, etc) I have bound to the AutoCompleteBox.
I don't think I can modify the datatemplate programmatically. Is there a way I can do this with binding (relative source)?
I am not sure if this works, but I think you could bind the text directly to the ValueMemberBinding property and use a converter to get the text out of it...
<TextBlock Text="{TemplateBinding DisplayMember}" />
Thank you for the suggestions.
I was unable to get a solution that I preferred, but my workaround is to just pass in a datatemplate resource as a property and that gets assigned to the autocompletebox itemtemplate.
Define a template:
<DataTemplate x:Key="myCustomDT">
<!-- whatever you want here -->
</DataTemplate>
Create the user control property for it:
public static DependencyProperty DisplayTemplateProperty = DependencyProperty.Register("DisplayTemplate", typeof(DataTemplate), typeof(myAutoComplete), null);
public DataTemplate DisplayTemplate {
get { return myACB.ItemTemplate; }
set { myACB.ItemTemplate = value; }
}
Now:
<local:myAutoComplete DisplayTemplate="{StaticResource myCustomDT}" />
Not the best method, but it will work for now.

Editable WPF ListBox

I have a ObservableCollection that's bound to a ListBox in WPF. I want the ListBox to be editable, and for the editing changes to be saved to the collection. Since WPF doesnt provide an editable listbox, I've tried creating my own by changing the ListBox.ItemTemplate.
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="EditableText" Text="{TemplateBinding Content}"/>
</DataTemplate>
</ListBox.ItemTemplate>
Changing the ItemTemplate gives me editable boxes, but any changes to the textboxes dont get saved to the ObservableCollection. Is there a way to have an editable ListBox with two way binding?
You cannot do it this way.
To achieve that kind of trick, you would need your items to be "holder classes" that expose a property you can bind your textbox to.
To understand it, imagine the following pseudo sequence of calls:
class ListBox
{
Bind(Items)
{
foreach(var item in Items)
{
DataTemplate Template = LoadTemplateForItem(item.GetType()); // this is where your template get loaded
Template.Bind(item); //this is where your template gets bound
}
}
}
Your template (the DataTemplate with the listbox) is loaded and the item (which I assume is a string in your case) gets passed in.
At this point, it only knows the string, and cannot influence anything upwards. A two-way binding cannot influence the collection because the template does not know in which context it is being used, so it cannot reach back to the original collection and modify its contents.
For that matter, this is the same thing for the TextBox. If it is not given a conainer and a property name, it has nowhere to "store back" the changes.
This basically the same as passing a string into a function call. The function cannot change which string was passed in (ignoring tricks such as by-reference argument passing).
To get back to your case, you need to build a collection of objects which expose a property containing the value that needs to be edited:
public class MyDataItem
{
string Data { get; set;}
}
Then you can bind your ListBox to a collection of those items and modifiy your datatemplate:
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="EditableText" Text="{Binding Data, Mode=TwoWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
Bind to a model property -- i.e. a property of the data object -- rather than to a view property such as Content. For example:
// model class
public class Widget : INotifyPropertyChanged
{
public string Description { ... }
}
<!-- view -->
<DataTemplate>
<TextBox Text="{Binding Description}" />
</DataTemplate>
Note this will not work if your ItemsSource is ObservableCollection (because there's no property to bind to).

Categories