Background: I'm new to WPF and have been trying to teach myself for a couple weeks now. I have an app that runs in a NavigationWindow with a few pages. The page in question has 5 textboxes, 4 of which are backed with dependency properties. Three of them are set up with ValidationRules for times, the fourth has ValidationRules for type double. The fifth textbox is the output of the calculation made from a button click event. The button is bound to a MultiDataTrigger, which enables the button when there are no validation errors. Buddy says "hey you have everything bound already, why not update the output box on binding so you don't have to click a button?".
This seems like a good idea and a nice weapon to put in my wpf toolbox. The button serves two purposes, to calculate the time for the output textbox, and to offer to navigate to another page with the current values. If I could show the result of the calculation in the textbox with a binding, I would just use the button to navigate to the next page. I've tried setting up an ObjectDataProvider to use with the fifth textbox so I can call a method to populate the result with a binding. So far I've only succeeded in causing numerous errors, including causing a stackoverflow on the page call to InitializeComponent();
public static readonly DependencyProperty timeBoxProperty =
DependencyProperty.Register("timeBox", typeof(string),
typeof(TtlPage), new UIPropertyMetadata("07:30"));
public static readonly DependencyProperty timeBoxProperty2 =
DependencyProperty.Register("timeBox2", typeof(string),
typeof(TtlPage), new UIPropertyMetadata("13:00"));
public static readonly DependencyProperty timeBoxProperty3 =
DependencyProperty.Register("timeBox3", typeof(string),
typeof(TtlPage), new UIPropertyMetadata("13:40"));
public static readonly DependencyProperty hoursBoxProperty =
DependencyProperty.Register("hoursBox", typeof(string),
typeof(TtlPage), new UIPropertyMetadata("9.00"));
public string timeBox
{
get { return (string)GetValue(timeBoxProperty); }
set { SetValue(timeBoxProperty, value); }
}
public string timeBox2
{
get { return (string)GetValue(timeBoxProperty2); }
set { SetValue(timeBoxProperty2, value); }
}
public string timeBox3
{
get { return (string)GetValue(timeBoxProperty3); }
set { SetValue(timeBoxProperty3, value); }
}
public string hoursBox
{
get { return (string)GetValue(hoursBoxProperty); }
set { SetValue(hoursBoxProperty, value); }
}
Part of button click, given the above, should I be accessing the textbox.text like below using the Textbox.Name property, or should I be grabbing it from the property or DependencyProperty above?:
private void Button_Click(object sender, RoutedEventArgs e)
{
DateTime inTime = DateTime.Parse(ttlInTime.Text);
DateTime outLunch = DateTime.Parse(ttlOutLunch.Text);
DateTime inLunch = DateTime.Parse(ttlInLunch.Text);
decimal hours = decimal.Parse(ttlHours.Text);
//etc.
}
The method for the ObjectDataProvider:
public string UpdateOutput()
{
//do stuff
}
Some XAML ObjectDataProvider, one of the input textboxes, and the output textbox:
<ObjectDataProvider x:Key="outputBox" ObjectType="{x:Type sys:String}" MethodName="UpdateOutput"/>
<Style x:Key="timeBox3" TargetType="TextBox" BasedOn="{StaticResource tbStyle}">
<Setter Property="Text">
<Setter.Value>
<Binding ElementName="This" Path="timeBox3" UpdateSourceTrigger="
<Binding.ValidationRules>
<local:TimeValidation/>
</Binding.ValidationRules>
</Binding>
</Setter.Value>
</Setter>
</Style>
<TextBox Name="ttlInLunch" Style="{StaticResource timeBox3}" Grid.Row="2" Grid.Column="1" TextChanged="TimeBox_TextChanged"
GotFocus="TimeBox_GotFocus"/>
<TextBox Margin="0,2,2,1" Name="ttlOutput" Grid.Row="4" Grid.Column="1" IsReadOnly="True" Background="Transparent" IsTabStop="False"
Text="{Binding Source={StaticResource outputBox}}"/>
So, I've been here http://msdn.microsoft.com/en-us/library/aa348824(v=vs.110).aspx, and worked with the example, and after a while, realized that the ObjectType wasn't supposed to be the return type of the method. It was actually just the name of the containing class, so I used ttlPage as the type (which is the page itself ttlPage : Page), and caused a stack overflow. I've done a ton of Googling and haven't come up with anything helpful. I haven't created any sort of converter for it, because the method returns a string, which I would assume is suitable for the textbox.text property. I've set a breakpoint in the UpdateOutput method, and have found that it doesn't even get called. How do I call the UpdateOutput method and have it's result bound to the output textbox while the user is typing? As far as when I calculate, I was just going to return from the method until there are no validation errors, at which point I would perform my calculations and return the calculated value ToString();