How do I read Text property of silverlight toolkit NumericUpDown control? - c#

I want to read value entered in the NumericUpDown control. How do i read it?
XAML Layout is follows
<StackPanel Style="{StaticResource StackPanelStyle_LableValue}">
<TextBlock Style="{StaticResource TextBlockStyle}"
Text="{Binding Path=ViewItem.Addition, Source={StaticResource LocalizedStrings }}" />
<inputToolkit:NumericUpDown Style="{StaticResource NumericUpdownStyle_Addition}"
Value="{Binding Items.RightSpecGlass.Addition, Mode=TwoWay}"
TabIndex="8" />
</StackPanel>

You can use
numericUpDown.Value; // To get decimal value of control
or
numericUpDown.Text; // To get value as string of control

Well, Since you have bind your view context, I think there is no reason to avoid get NumericUpDown's value except :
1- Maybe you forgot to initialize those classes or properties Items and/or RightSpecGlass
2- Your class doesn't implement INotifyPropertyChanged to raise when any control's value change in view. Addition property has to raise property change event in its setter.
public event PropertyChangedEventHandler PropertyChanged;
public virtual void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
private int _addition;
public Int32 Addition
{
get { return _addition; }
set
{
_addition= value;
RaisePropertyChanged("Addition");
}
}
hope this help.

Related

ObservableCollection data binding during runtime

I have a slight issue. I am making a calendar application with some listbox elements. Each calendar view retrieves it's "calendar events" from a dictionary where TKey = DateTime and TValue = ObservableCollection <CalendarEvent>. Now this works fine for any calendar day where there are predefined events already. I can data bind the listbox to a property that contains a reference to the dictionary entry of that particular calendar day. However another feature of my application should be the ability to add events during runtime. What I have done right now is, if there is no dictionary key present for that particular calendar day it just sets the Events property to null and then I change it during runtime if an event was added for that day, unfortunately it doesn't seem to like that, it doesn't "bind" properly or so to say.
Here is the code
public CalendarDayView(DateTime date)
{
DataContext = this;
Date = date;
Events = CalendarRepository.Instance.Entries.ContainsKey(date) ? CalendarRepository.Instance.Entries[date] : null;
}
public DateTime Date { get; set; }
public ObservableCollection<CalendarEvent> Events { get; set; }
/// <summary>
/// This method will set the listbox item source to the ObservableCollection if it hasn't been set already
/// </summary>
public void UpdateItemSource()
{
if (Events == null)
// This is the part that doesn't do anything unfortunately
Events = CalendarRepository.Instance.Entries[Date];
}
XAML markup
<ControlTemplate TargetType="{x:Type local:CalendarDayView}">
<Border BorderBrush="Gray" BorderThickness="0.2" Width="100" Height="100">
<Grid Name="contentGrid">
<ListBox
Name="entriesListBox" Background="LightYellow" FontSize="10"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Events}">
</ListBox>
<!-- Date display below -->
<TextBlock
Name="dateTextBlock" Text="{Binding Date, StringFormat={}{0:dd-MMM}, UpdateSourceTrigger=PropertyChanged}"
FontFamily="Segoe UI Light" FontSize="18" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"/>
</Grid>
</Border>
</ControlTemplate>
I don't see you raising the PropertyChanged event anywhere to notify the view of binding changes. You should implement INotifyPropertyChanged on the CalendarDayView model and raise the implemented PropertyChanged event in your property setters that are used as binding source (Events in this case).
The following code shows a simple example, but it might be better to add the PropertyChanged functionality to a base model class.
public class CalendarDayView : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<CalendarEvent> _events;
public ObservableCollection<CalendarEvent> Events
{
get { return _events; }
set
{
_events = value;
RaisePropertyChanged("Events");
}
}
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}

Data binding to singleton class

I've searched here a number of times and found a bunch of examples, but can't seem to get anything to work.
I've got a solution set up where a ViewModel refers to a MainViewModel class through a locator. The main view model class has:
public NotifyLog Log
{
get { return LogMgr.Instance.Log; }
}
In it. This allows me to specify:
<TextBox IsEnabled="True" Text="{Binding Log.Text, Mode=OneWay}" />
The NotifyLog is defined as:
public class NotifyLog : INotifyPropertyChanged
{
public NotifyLog()
{
_Log = new StringBuilder();
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public event PropertyChangedEventHandler PropertyChanged;
private StringBuilder _Log;
public void Append(String Value)
{
_Log.Append(Value);
OnPropertyChanged("Text");
}
public string Text
{
get { return _Log.ToString(); }
}
public override string ToString()
{
return this.Text;
}
}
For the initial start of the application, the text box is populated but, the OnPropertyChanged handler is never automatically populated by the binding so no changes are detected. I'm doing something wrong, I just don't know what...
Thanks for your time,
BlD
if you want to update the log when typing in the text box you need to change the binding mode to TwoWay. also the event is triggered when you exit from the text box, not on each char typed.
if you want to update the text box when the log is changed you need to add a setter to the Text property and raise the NotifyPropertyChanged event (in the setter).
also check the output of the program for some binding errors.
To the line:
<TextBox IsEnabled="True" Text="{Binding Log.Text, Mode=OneWay}" />
Try adding the "UpdatedSourceTrigger" like so:
<TextBox IsEnabled="True" Text="{Binding Log.Text, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />

Data binding to textblock does not update

I am trying to get the get the sum to update in the textblock, however I'm only able to get it updated through restarting the windows phone emulator. Why is it so?
Code in DisplayBill.xaml
<TextBlock x:Name="lbTotalAmt" Text="{Binding Path=Sum, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="0,364,0,10" Grid.Row="1" />
Code in ViewModel.cs
private string _Sum;
public string Sum
{
get {return _Sum;}
set
{
_Sum = value;
NotifyPropertyChanged("Sum");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify Silverlight that a property has changed.
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
if (propertyName == "ToDoBills")
UpdateSumValue();
}
private void UpdateSumValue()
{
Sum = ToDoBills.Sum(i => i.Amount).ToString();
}
#endregion
Update
What I'm trying to do is to update the textblock everytime the listbox adds an item. so everytime a new item is added into the listbox, the textblock which display the total amount will update. So my question is how do I go about updating my textblock everytime a new item is added into the listbox? Can anyone help me please? I tried using the binding expression below but to no avail
public DetailPageBill()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.todoViewModel;
BindingExpression be = lbTotalAmt.GetBindingExpression(TextBlock.TextProperty);
be.UpdateSource();
}
Try setting UpdateSourceTrigger to PropertyChanged for your TextBlock's binding:
<TextBlock x:Name="lbTotalAmt" Text="{Binding Path=Sum, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,364,0,10" Grid.Row="1" />
With Explicit no automatic update is performed. MSDN says:
Updates the binding source only when you call the
UpdateSource method.
See MSDN on UpdateSourceTrigger for more information.

NotifySourceUpdated & Binding.SourceUpdated not working

My event below (OnSourceUpdated) is not getting handled.
XAML:
<StackPanel x:Name="MyStackPanel"
Orientation="Horizontal"
DockPanel.Dock="Top">
<TextBox Text="{Binding Side, Mode=TwoWay}"
Width="100"/>
<TextBlock Background="Yellow"
Text="{Binding Side, Mode=OneWay,
NotifyOnSourceUpdated=True}"
Width="100"
SourceUpdated="OnSourceUpdated"
Binding.SourceUpdated="OnSourceUpdated"/>
</StackPanel>
C#:
....
MyStackPanel.DataContext = new MyItemClass() { Side = "Test" };
....
private void OnSourceUpdated(Object sender, DataTransferEventArgs args)
{
var i = args.Property;
}
public class MyItemClass : INotifyPropertyChanged
{
private string _side;
public string Side
{
get { return _side; }
set
{
_side = value;
OnPropertyChanged("Side");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
I have all the relevant settings done like NotifyOnSourceUpdated & SourceUpdated & Binding.SourceUpdated etc.
From msdn: Binding.SourceUpdated attached event occurs when a value is transferred from the binding target to the binding source, but only for bindings with the NotifyOnSourceUpdated value set to true
In the Binding of TextBlock, there is no value transfer from the binding target (TextBlock.Text) to the binding source (Side). Thus SourceUpdated cannot be fired.
Instead SourceUpdated can be fired on the first binding. Indeed here the target binding TextBox.Text can change the binding source (Side).
Maybe I'm missing something, but I'm thinking your approach to updating is a bit strange. Is there a reason you're not just going with
<TextBlock Text="{Binding foo, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" ... />
If you're just interested in updates coming from source, that's normally the way of doing it. Calling
OnPropertyChanged( "PropertyName" )
covers the rest.

Binding to change the property

Is it usable or this doesn't work: to change the Text Box.Text and the property behind to change can a binding of this type be made(i know that this can be made with an event from Text Box, i am looking for some kind of binding that can be made) ?
Should i just use Text Box.Text in my cod?
<TextBox Text="{Binding Path=NumeClient, Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="117,21,0,0" Name="textBox1" VerticalAlignment="Top" Width="249" />
public string NumeClient { get; set; }
If I understand the question correctly, you're asking how to setup a two way binding to the Text property of a TextBox?
<TextBox Text="{Binding Path=YourProperty, Mode=TwoWay}" />
This Makes both your property changes the TextBox and the TextBox changes the property (from MSDN)
Add in your class contructor DataContext = this;
public class Person : INotifyPropertyChanged
{
private string name;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
public string PersonName
{
get { return name; }
set
{
name = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("PersonName");
}
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
XAML :
<TextBox Text="{Binding Path=PersonName, Mode=TwoWay}" />
Hope it helps

Categories