0
votes

I have a UWP app in C # with SQLite.

The problem I have is with the datepicker, when DatetimeOffsetTimeConverter gives me an exception, if I remove the date 01/01/1001 (to make it out the correct date), the date of the DatePicker comes in another page, called Mypetpage. c# private async void AddButton_Click(object sender, RoutedEventArgs e) {

       var  selectedDate =Data1.Date.ToString();



        DataBaseHelper Db_Pet = new DataBaseHelper();
       if (txtnombre.Text != "" & txtchip.Text !="" & txtraza.Text !=""  & SelectedgeneroText !="" & txtcolor.Text != ""  )
        {
            Db_Pet.Insert(new Mascota(txtnombre.Text, txtchip.Text, txtraza.Text, SelectedgeneroText, txtcolor.Text, selectedDate));
        }
        else
        {
            MessageDialog md = new MessageDialog("Enter your pet");
            await md.ShowAsync();
        }

    }

xaml

<DatePicker x:Name="Data1" Grid.Row="1"
       Date="{Binding someDate, Mode=TwoWay, Converter={StaticResour DateTimeToDateTimeOffsetConverter}}"/>

ViewModel

    public void CreateDataBase(string DB_PATH)
    {
        if (!CheckFileExists(DB_PATH).Result)
        {
            using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), DB_PATH))
            {
                conn.CreateTable<Mascota>();
                conn.CreateTable<Clinico>();


            }
        }
    }

    protected async Task<bool> CheckFileExists(string fileName)
    {
        try
        {
            var petstore = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(fileName);

            return true;
        }
        catch
        {
            return false;
        }
    }

    public void Insert(Mascota objMascota)
    {
        using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
        {
            conn.RunInTransaction(() =>
            {

                conn.Insert(objMascota);
            });
        }
    }

    public Mascota ReadMascota(int mascotaid)
    {
        using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
        {
            var existmascot = conn.Query<Mascota>("select * from Mascota where Id =" + mascotaid).FirstOrDefault();
            return existmascot;
        }
    }

    public ObservableCollection<Mascota> ReadAllMascota()
    {
        try
        {
            using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
            {

                List<Mascota> myMascota = conn.Table<Mascota>().ToList<Mascota>();
                ObservableCollection<Mascota> MascotaList = new ObservableCollection<Mascota>(myMascota);
                return MascotaList;
            }
        }
        catch
        {
            return null;
        }
    }

    //borra todo

    public void DeleteAllMascota()
    {
        using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
        {

            conn.DropTable<Mascota>();
            conn.CreateTable<Mascota>();
            conn.Dispose();
            conn.Close();
        }


    }


    public void DeleteMascota(int Id)
    {
        using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
        {
            var existmascot = conn.Query<Mascota>("select * from Mascota where Id =" + Id).FirstOrDefault();
            if (existmascot != null)
            {
                conn.RunInTransaction(() =>
                {
                    conn.Delete(existmascot);
                });
            }
        }
    }
1
What is the exception? Show code from datacontextmiechooy
Windows.UI.Xaml.Markup.XamlParseException: 'No se pudo encontrar el texto asociado a este código de error. Cannot find a Resource with the Name/Key DateTimeToDateTimeOffsetConverter [Line: 81 Position: 24]'user3682557
Is it a typo StaticResour, shouldn't it be StaticResource?Keyur PATEL
Then as I can solve, the exceptionuser3682557
Also the code snippet about DateTimeToDateTimeOffsetConverter please if you still have issue.Sunteen Wu

1 Answers

1
votes

## EDIT-1 ##

So, i've made up a quick sample for all the possible cases that can be used to resolve your issue. you can pick any one. You can copy paste the code into your new project and you'll be able to see it.

The XAML

<Page
x:Class="DateTimeBinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DateTimeBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:ViewModels="using:DateTimeBinding.ViewModels"
xmlns:Converters="using:DateTimeBinding.Converters">

<Page.DataContext>
    <ViewModels:MainPageViewModel x:Name="ViewModel"/>
</Page.DataContext>

<Page.Resources>
    <Converters:DateTimeToDateTimeOffsetConverter x:Key="DateTimeToDateTimeOffsetConverter"/>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Padding="10">
        <TextBlock TextWrapping="WrapWholeWords">
            <Run Text="Scenario 1:" FontWeight="SemiBold"/>
            <Run Text=" Using the DateTime Picker and simple backing property"/>
        </TextBlock>
        <DatePicker HorizontalAlignment="Center" Margin="10" Date="{x:Bind ViewModel.SelectedDate,Mode=TwoWay,Converter={StaticResource DateTimeToDateTimeOffsetConverter}}"/>
        <TextBlock Text="{x:Bind ViewModel.SelectedDateString,Mode=OneWay}"/>
        <Border BorderThickness="0,0,0,1" BorderBrush="Gray" Margin="10"/>
        <TextBlock TextWrapping="WrapWholeWords">
            <Run Text="Scenario 2:" FontWeight="SemiBold"/>
            <Run Text=" Direct Element x:Bind"/>
        </TextBlock>
        <DatePicker x:Name="SelectDatePicker" HorizontalAlignment="Center" Margin="10" Date="{x:Bind ViewModel.SelectedDate,Mode=TwoWay,Converter={StaticResource DateTimeToDateTimeOffsetConverter}}"/>
        <TextBlock Text="{x:Bind SelectDatePicker.Date,Mode=OneWay}"/>
        <Border BorderThickness="0,0,0,1" BorderBrush="Gray" Margin="10"/>
        <TextBlock TextWrapping="WrapWholeWords">
            <Run Text="Scenario 3:" FontWeight="SemiBold"/>
            <Run Text=" Using a Calender Picker control instead"/>
        </TextBlock>
        <CalendarDatePicker x:Name="CalenderPicker" Date="{x:Bind ViewModel.SelectedDate,Mode=TwoWay,Converter={StaticResource DateTimeToDateTimeOffsetConverter}}" HorizontalAlignment="Center" Margin="10"/>
        <TextBlock Text="{x:Bind CalenderPicker.Date,Mode=OneWay}"/>
    </StackPanel>
</Grid>

Please Note: I've used x:Bind instead of legacy Binding for performance and you should prefer compile time binding too. Just not in case of a TextBox as UpdateSourceTrigger is not available in x:Bind. Prefer legacy binding there incase you want to bind in a twoWay mode.

Your ViewModel:

internal class MainPageViewModel : INotifyPropertyChanged
{
    private DateTime selectedDate = DateTime.Now;
    /// <summary>
    /// Backing property for the Selected Date in the Date Picker.k
    /// </summary>
    /// <value>
    /// The selected date.
    /// </value>
    public DateTime SelectedDate
    {
        get { return selectedDate; }
        set
        {
            if (value.Date != selectedDate.Date)
            {
                selectedDate = value;
                RaisePropertyChanged(nameof(SelectedDate));
                RaisePropertyChanged(nameof(SelectedDateString));
            }
        }
    }

    public string SelectedDateString => SelectedDate.ToString("dd MMM yyyy");


    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    #endregion INotifyPropertyChanged
}

This is a basic implementation of it. Personally I would prefer the scenario 3 or scenario 2, because of which I don't have to have any ViewModel Code. I've still done an {x:bind} in both the scenarios just to keep the supporting properties updated. They are not needed if going with scenario 2 or 3.

Your Converter:

 public class DateTimeToDateTimeOffsetConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            if (value != null)
            {
                DateTime date = (DateTime)value;
                return new DateTimeOffset(date);
            }
            return new DateTimeOffset(DateTime.Now);
        }
        catch (Exception)
        {
            return DateTimeOffset.MinValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        try
        {
            DateTimeOffset dto = (DateTimeOffset)value;
            return dto.DateTime;
        }
        catch (Exception)
        {
            return DateTime.MinValue;
        }
    }
}

You won't need this as well if you go with scenario 3 or 2 but in that case you might want to use a DateFormatter converter which converts the entire DateTime to a more readable or desirable format.

Old Guesswork


There might be a few things going wrong. We'll escalate gradually,

  1. The Typing mistake of StaticResouce.
  2. The Converter in not initialized in your App.xaml or your converter dictionary (ResourceDictionary).
  3. This is an extension of the point 2, you can also initialize your converter on the page where your converter is being used.
  4. If the Converter is declared (like <converters:DateTimeToDateTimeOffsetConverter x:Key="DateTimeToDateTimeOffsetConverter"/>) the key might be wrong.