Using silverlight datepicker and timepicker together - silverlight

I'm using the Silverlight DatePicker and TimePicker from the toolkit together to allow a user to select a date and time. They are bound to the same DateTime value on a business object behind the scences. This mostly works okay, except when the date component is changed the time component is wiped. This is kinda logical but probably not the behaviour the user wanted.
There's a couple of ways I could hack my way round this:
Store the date and time components in different values (not that hacky but a little anonying as I'm going to store the resulting value as one field in a db)
Try and fix up the time component when the SelectedDateChanged event fires (which does seem a very hacky solution)
I'd like to be able to tell the DatePicker control: just leave the time component when you change date. Am I hoping for too much?

I think, you can say DatePicker "Just leave the time component when you change date" using converter :). When you are binding DateTime to DatePicker converter stores value, and on ConvertBack returns without changes in Time part.
public class DateConverter : IValueConverter
{
private DateTime _original;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
_original = (DateTime)value;
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime date = ((DateTime) value);
return new DateTime(date.Year, date.Month, date.Day, _original.Hour, _original.Minute, _original.Second);
}
}
XAML:
<sdk:DatePicker SelectedDate="{Binding Date, Mode=TwoWay,
Converter={StaticResource dateConverter}}" />
<input:TimePicker Value="{Binding Date, Mode=TwoWay}"/>

Related

IValueConverter uses the wrong culture with DateTime

Hi the below code is used to convert the DateTime format to current thread culture format
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is DateTimeOffset?)
{
var dto = (DateTimeOffset?)value;
return dto.Value.ToString("t", culture);
}
return null;
}
But the DateTimeFormat in culture parameter is not updating to the current system datetime format, instead it uses the fixed format like HH:mm tt for short time.
The workarond for this is to set the language from the current thread as below, which we have done in App.Xaml but still DateTimeFormat will have the default format.
// fixes culture-specific binding formatting. See this link: WPF Binding StringFormat Short Date String
this.Language = System.Windows.Markup.XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.IetfLanguageTag);
I have gone through some blogs on this and looks like its a bug in WPF. Some guys suggest not to rely on culture for DateTime as DateTimePicker should give a selected date formatted to the local thread culture. This works fine if we remove the culture parameter in ToString().
Please provide your suggestions or solution for this :)
Maybe you need to set the language also on the WPF controls
(also in App.xaml.cs)
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

how to link two datepickes so that one's date cannot be greater or less then others'

I am programming in WPF and in having an interface where Manufacturing date and Expiry date are two date pickers. How can I set my expiry date Date picker to select date only greater then mfg date?
The WPF datepicker doesn't have a minimum date property unfortunately, although it does have a DisplayDateStart dependency property. Within the calendar pop-up part of a datepicker control, this property hides dates prior to the assigned value.
However, users will be still be able to enter any expiry date using the textbox part of the datepicker. In order to handle this, you'll need to validate the SelectedDate properties of both datepickers.
I've attached code which does both (for the purpose of this question, I have assumed you're not using MVVM - if you are let me know):
Firstly, in XAML, the DisplayDateStart dependency property of the expiry datepicker is bound to the SelectedDate dependency property of the manufacturing datepicker (thus hiding invalid dates in the expiry datepicker calendar pop-up). As your requirement states "only greater than mfg date" a value converter is required to return the day after the manufacturing day.
<StackPanel>
<StackPanel.Resources>
<yournamespace:NextDayConverter x:Key="NextDayConverter" />
</StackPanel.Resources>
<DatePicker x:Name="ManufacturingDatePicker"
SelectedDateChanged="OnSelectedDateChanged" />
<DatePicker x:Name="ExpiryDatePicker"
SelectedDateChanged="OnSelectedDateChanged"
DisplayDateStart="{Binding
ElementName=ManufacturingDatePicker,
Path=SelectedDate,
Converter={StaticResource NextDayConverter}}" />
</StackPanel>
The NextDayConverter is detailed below:
namespace YourNamespace
{
using System;
using System.Globalization;
using System.Windows.Data;
public sealed class NextDayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
DateTime manufacturingDate = (DateTime)value;
DateTime minimumExpiryDate = manufacturingDate.AddDays(1);
return minimumExpiryDate;
}
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Secondly, in code behind, there's a handler for the SelectedDateChanged event of both datepickers. The validation code in here sets the expiry date to the manufacturing date if the user enters an invalid expiry date (i.e. prior or equal to the manufacturing date).
private void OnSelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
if (ManufacturingDatePicker.SelectedDate.HasValue &&
ExpiryDatePicker.SelectedDate.HasValue &&
ExpiryDatePicker.SelectedDate <= ManufacturingDatePicker.SelectedDate)
{
ExpiryDatePicker.SelectedDate = ManufacturingDatePicker.SelectedDate.Value.AddDays(1);
}
}
I hope this helps.

Flexing date format in XAML at runtime

Based on a setting in my application I need to be able to show different formats of showing a Date in XAML. For example it needs to be either in "yyyy/MM/dd" format or in "MM/dd/yyyy" format.
What are some ways that I can achieve this? Please note that the places in my application that I need to handle this are limited so even a "fix on the spot" type of solution would work in my case too.
Thanks for suggestions.
You can use a ValueConverter for this. Just replace YourApplicationSettings.YearFirst with wherever you're pulling the setting from.
public class DateTime2FlexibleDateString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var dt = value as DateTime?
if (dt== null)
{
return null;
}
var dateTime = dt.Value;
if (YourApplicationSettings.YearFirst)
{
return dateTime.ToString("yyyy/MM/dd");
}
return dateTime.ToString("MM/dd/yyyy");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
Then either in each xaml file that needs it, or in a App.xaml (or a resource dictionary added to App.xaml), add a static resource for your converter.
<UserControl.Resources>
<converters:DateTime2FlexibleDateString x:Key="DateTime2FlexibleDateString" />
</UserControl.Resources>
And then when you bind to the date, specify the converter.
<TextBlock Text="{Binding MyDateTimeVariable, Converter={StaticResource DateTime2FlexibleDateString}" />
It depends on the context of what you are doing, but if you are binding to a DateTime then you can alter the StringFormat property like so:
<TextBlock Text="{Binding MyDateTimeVariable, StringFormat='yyyy/MM/dd'}" />
<TextBlock Text="{Binding MyDateTimeVariable, StringFormat='MM/dd/yyyy'}" />
Here is a good example of some different format options that be achieved like this.

how to showing time elapsed in a media element in silverlight?

how can i showing time elapsed of a video file who is playing in a MediaElement control in silverlight?
There is a Position property on the MediaElement. This video and source code should help you out http://www.silverlight.net/learn/quickstarts/audioandvideo/
Finally i resolve my problem with this way:
i use a Textblock control and bind text property to Position property of MediaElement control, then i use a IvalueConverter to show appropriate Time in TextBlock:
<TextBlock MinWidth="40" Text="{Binding ElementName=myMediaElement, Path=Position, Converter={StaticResource TimeConverterFormatter}}"/>
TimeConverterFormatter is a class for convert TimeSpan value to short time format. because position property in MediaElement show a Timespan value like to "0:00:00:00.0000000" and i want elapsed time value like to this: "00:00"
public class TimeConverterFormatter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value.ToString().Length == 16)
return value.ToString().Substring(3, 2) + ":" + value.ToString().Substring(6, 2);
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
I realise that this is an old question now, but in WPF you can just use a normal StringFormat to do what you want:
<TextBlock Text="{Binding Position, ElementName=myMediaElement,
StringFormat={}{0:hh}:{0:mm}, FallbackValue=00:00, Mode=OneWay}" />
I couldn't work out whether you wanted hours and minutes or minutes and seconds, so here is the latter:
<TextBlock Text="{Binding Position, ElementName=myMediaElement,
StringFormat={}{0:mm}:{0:ss}, FallbackValue=00:00, Mode=OneWay}" />
I can't guarantee that it will work in Silverlight though.
Not sure about Silverlight but this should work to show mm:ss.
lblLength.Content = String.Format("{0:mm}:{0:ss}", mediaElement.Position);

Clearing Textbox does not set binding to null

I am having difficulty setting an empty TextBox to null on an nullable DB Field.
XAML
<y:TextBox Text="{Binding Year1Cost, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
StringFormat=\{0:c\}}" Grid.Row="3" Grid.Column="1" />
When I enter any value into it the binding is fine and the entered value is passed
When I leave a null value alone a null is passed
If I delete the value from the TextBox the value passed is the Original value of the Textbox and the UI is not notified of the change Grrrrrrrrrrrrrrrr
I have spent a long time checking out options
nothing short of putting code behind the OnTextChanged of every nullable field I cannot see the efficiency in doing this.
Thanks in advance:
ps. Have looked at TargetNullValue to no success
Visual Studio 2008 - SP1 - .Net 3.5
Set the property TargetNullValue of the binding to String.Empty:
<TextBox Text="{Binding TargetNullValue={x:Static sys:String.Empty}}"/>
I tried it and it works for me.
And if I am not wrong (please forgive me if I am), you should set the property StringFormat like this:
StringFormat={}{0:C}
This is even probably the reason of the exception you got.
Consider using a value converter. You should be able to implement the ConvertBack method to translate empty strings into nulls.
For me only converter works :
Here's a link
public class NullableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? string.Empty : String.Format(culture, "{0}", value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.IsNullOrEmpty(String.Format(culture, "{0}", value)) ? null : value;
}
}

Resources