I have a longlistselector to show a gallery of the projects that I have in my app. Every item of the longlistselector have an image of the project, the name and an image to share it in social networks. The problem is that I need know when I touch the share image to leave to a different page that allow us to share it. This is the gallery longlistselector xaml:
<phone:LongListSelector x:Name="GaleryLongListSelector" SelectionChanged="GaleryLongListSelector_SelectionChanged" Margin="0,0,0,15">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Margin="-20,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="12,2,0,4" Height="100" toolkit:TiltEffect.IsTiltEnabled="True" Grid.Column="0">
<Image Width="80" RenderTransformOrigin="0.5,0.5" Height="80" Source="{Binding ThumbImage}">
<Image.RenderTransform>
<RotateTransform Angle="90"/>
</Image.RenderTransform>
</Image>
<!--<StackPanel Orientation="Vertical">-->
<TextBlock x:Name="txtProjectName" Margin="20,0" VerticalAlignment="Center" Text="{Binding Name}" Style="{StaticResource PhoneTextNormalStyle}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" />
<!--<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<TextBlock x:Name="txtProjectDescript" Text="Aqui iria una descripcion muy larga del faldksjfjkldjfkldajsfkljaslfkjasldfjlasdjfkl" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeLarge}"/>
</ScrollViewer>-->
<!--</StackPanel>-->
</StackPanel>
<Image Source="/Images/share.png" Height="50" Tap="Image_Tap" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="True" x:Name="ContextMenu">
<toolkit:MenuItem Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.MainPagePanoramaItemGalleryContextMenuDelete}" Click="Delete_Click"/>
<toolkit:MenuItem Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.MainPagePanoramaItemGalleryContextMenuRename}" Click="Rename_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
I read the item selected in a "SelectionChanged" event like this:
private void GaleryLongListSelector_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (GaleryLongListSelector != null && GaleryLongListSelector.SelectedItem != null)
{
var selectedItem = (Project)GaleryLongListSelector.SelectedItem;
var id = selectedItem.ID;
NavigationService.Navigate(new Uri("/ProjectViewPage.xaml?projectID=" + id.ToString(), UriKind.Relative));
}
}
I can use the tap event of the image but using this method I can't find the index of the longlistselector item touched.
Thanks everyone!!
Use the IndexOf() method on your ItemsSource colelction..
var dataItems = GaleryLongListSelector.ItemsSource as List<Project>;
var selectedItem = (Project)GaleryLongListSelector.SelectedItem;
var indexOfSelectedItem = dataItems.IndexOf(selectedItem)
public partial class MainPage : PhoneApplicationPage
{
public Product selectedItemData;
// Constructor
public MainPage()
{
InitializeComponent();
lsttest.ItemsSource = App.lstp;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void Add_Click_1(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri(#"/Page2.xaml", UriKind.Relative));
}
private void lsttest_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
selectedItemData = e.AddedItems[0] as Product;
NavigationService.Navigate(new Uri(#"/Page2.xaml", UriKind.Relative));
}
// Sample code for building a localized ApplicationBar
//private void BuildLocalizedApplicationBar()
//{
// // Set the page's ApplicationBar to a new instance of ApplicationBar.
// ApplicationBar = new ApplicationBar();
// // Create a new button and set the text value to the localized string from AppResources.
// ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
// appBarButton.Text = AppResources.AppBarButtonText;
// ApplicationBar.Buttons.Add(appBarButton);
// // Create a new menu item with the localized string from AppResources.
// ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
// ApplicationBar.MenuItems.Add(appBarMenuItem);
//}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Page2 destinationpage = e.Content as Page2;
if (destinationpage != null)
{
// Change property of destination page
destinationpage.GetProduct = selectedItemData;
}
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//Page2 destinationpage = e.Content as Page2;
//if (destinationpage != null)
//{
// // Change property of destination page
// destinationpage.GetProduct = selectedItemData;
//}
}
}
public partial class Page2 : PhoneApplicationPage
{
public Product GetProduct { get; set; }
public Page2()
{
InitializeComponent();
}
private void Add_Click_1(object sender, RoutedEventArgs e)
{
Product p2 = stkProduct.DataContext as Product;
// p2.Name = txtName1.Text;
if (string.IsNullOrEmpty(p2.ID))
{
p2.ID = DateTime.Now.ToString("yyyyMMddhhmmsstt");
App.lstp.Add(p2);
}
else
{
int index = App.lstp.IndexOf(p2);
App.lstp.Remove(GetProduct);
App.lstp.Insert(index, p2);
}
NavigationService.Navigate(new Uri(#"/MainPage.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (GetProduct == null)
{
GetProduct = new Product();
ApplicationBarIconButton btn = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
btn.Text = "Add";
btn.IconUri = new Uri("/Assets/check.png", UriKind.Relative);
}
else
{
ApplicationBarIconButton btn = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
btn.Text = "save";
btn.IconUri = new Uri("/Assets/save.png", UriKind.Relative);
}
stkProduct.DataContext = GetProduct;
}
private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)
{
Product p2 = stkProduct.DataContext as Product;
// p2.Name = txtName1.Text;
if (string.IsNullOrEmpty(p2.ID))
{
p2.ID = DateTime.Now.ToString("yyyyMMddhhmmsstt");
App.lstp.Add(p2);
}
else
{
int index = App.lstp.IndexOf(p2);
App.lstp.Remove(GetProduct);
App.lstp.Insert(index, p2);
}
NavigationService.Navigate(new Uri(#"/MainPage.xaml", UriKind.Relative));
}
}
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="lsttest" SelectionChanged="lsttest_SelectionChanged_1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox x:Name="txtname" Text="{Binding Name}"></TextBox>
<TextBox x:Name="txtID" Text="{Binding ID}" Visibility="Collapsed"></TextBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
using System;
using System.IO.IsolatedStorage;
namespace MobileCartWL.HelperClasses
{
public class Helper
{
#region appSettings
public static IsolatedStorageSettings appSettings;
#endregion
//This function is used to insert Key,Value pair information in the Isolated Storage memory
#region InsertDetailInMemory
public static void InsertDetailInMemory(string key, object value)
{
try
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (!appSettings.Contains(key))
appSettings.Add(key, value);
else
appSettings[key] = value;
appSettings.Save();
}
catch (Exception) { }
}
#endregion
//This function is used to remove Key,Value pair information from the Isolated Storage memory
#region RemoveDetailInMemory
public static void RemoveDetailInMemory(string key)
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
appSettings.Remove(key);
appSettings.Save();
}
}
#endregion
//This function is used to check the existing of Key,Value pair information in the Isolated Storage memory
#region IsExistKeyInMemory
/// <summary>
/// Check if Specified Key Is Exists or not
/// </summary>
/// <param name="key">Key</param>
/// <returns>true if it exists otherwise return false</returns>
public static bool IsExistKeyInMemory(string key)
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
return true;
}
else
{
return false;
}
}
#endregion
//This function is used to get Key,Value pair information from the Isolated Storage memory
#region GetDetailFromMemory
/// <summary>
/// Get value from memory of Specified Key
/// </summary>
/// <param name="key">Key</param>
/// <returns>value as Object of Specified Key</returns>
public static object GetDetailFromMemory(string key)
{
object value = string.Empty;
try
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
value = appSettings[key];
}
return value;
}
catch (Exception)
{
return value;
}
}
#endregion
}
}
Related
I coding WPF App with Mahapps.Metro.
At that time, I’m cording a process that will display a dialog asking the user to select a directory and then display that directory in a Textbox.
Wrote the code shown below and got it to work, but the selected directory was not display in the Textbox.
xaml source:
<mah:MetroWindow x:Class="LogAnalysisProto_2.ToolLancher"
...
d:DataContext="{d:DesignInstance {x:Type local:ToolLancherViewModel},IsDesignTimeCreatable=True}"
mc:Ignorable="d"
Title="Sample" Height="610" Width="970"
>
<Grid>
<StackPanel Orientation="Horizontal">
<Label Style="{DynamicResource CommonLabel}" Content="Target Folder"/>
<Button x:Name="targetFolderOpen" Style="{DynamicResource MahApps.Styles.Button.Flat}" HorizontalAlignment="Center" Width="100" Margin="50,0,0,0" BorderBrush="{x:Null}" Background="{x:Null}" Click="targetFolderButton_Click">
<iconPacks:PackIconModern Width="30" Height="20" Kind="Folder" VerticalAlignment="Center"/>
</Button>
<TextBox x:Name="targetFolderTextBox" Text="{Binding TargetFolderPath}" Style="{DynamicResource MahApps.Styles.TextBox}" Height="32" Width="660" VerticalAlignment="Center"></TextBox>
</StackPanel>
</Grid>
</mah:MetroWindow>
code behind:
public partial class ToolLancher : MetroWindow
{
public ToolLancher()
{
DataContext = new ToolLancherViewModel();
InitializeComponent();
}
private void targetFolderButton_Click(object sender, RoutedEventArgs e)
{
var vm = DataContext as ToolLancherViewModel;
vm.PickTargetFolder();
//targetFolderTextBox.Text = vm.TargetFolderPath;
}
}
In ViewModel source(in ToolLancherViewModel):
public class ToolLancherViewModel : BaseViewModel
{
...
private string m_TargetFolderPath { get; set; }
/// <summary>
/// TargetFolder Property
/// </summary>
public string TargetFolderPath
{
get { return m_TargetFolderPath; }
set
{
m_TargetFolderPath = value;
IsExistsTargetDirectory = Directory.Exists(value);
NotifyPropertyChanged(nameof(TargetFolderPath));
}
}
/// <summary>
/// Select dialog path
/// </summary>
public void PickTargetFolder()
{
var path = PickFolder("TargetFolderBrowse");
if (string.IsNullOrEmpty(path)) return;
TargetFolderPath = path;
IsExistsTargetDirectory = true;
NotifyPropertyChanged(nameof(TargetFolderPath));
NotifyPropertyChanged(nameof(IsExistsTargetDirectory));
}
public static string PickFolder(string dialogTitle = "")
{
using (var folderPicker = new CommonOpenFileDialog()
{
Title = dialogTitle == string.Empty ? "SelectFolder" : dialogTitle,
InitialDirectory = initialDirectory,
IsFolderPicker = true,
})
{
if (folderPicker.ShowDialog() != CommonFileDialogResult.Ok)
{
return string.Empty;
}
return folderPicker.FileName;
}
}
}
BaseViewModel
public class BaseViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
var e = new PropertyChangedEventArgs(propertyName);
PropertyChanged?.Invoke(this, e);
}
}
Selecting Directory
After the Directory Select
There is no error.
Also, the binding method is already coded by me in another source, which is similarly written and works as expected.
In addition, the directory will appear in the TextBox without problems when specified in the following way.
private void targetFolderButton_Click(object sender, RoutedEventArgs e)
{
var vm = DataContext as ToolLancherViewModel;
vm.PickTargetFolder();
// Uncomment out this line
targetFolderTextBox.Text = vm.TargetFolderPath;
}
Correctly displayed example
I have a WPF of tasks each has status of completed or pending, I will view all of these items into a list box, the tasks are serialized into XML file and these items are linked to UI through ObersvableCollection.
What I'm looking for it so be able to filter the tasks on the view and be able to edit or create new taks and save into the XML file.
I was thinking about creating a new class called FilterTask.cs and have static method Completed() which return ObersvableCollection item but I am not sure if this will affect the serialization process.
here is my code
main window XAML
<Window x:Class="UIToDoList_2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:UIToDoList_2"
mc:Ignorable="d"
Title="To Do List" Height="290" Width="500" ResizeMode="CanMinimize">
<Grid Margin="0,0,0,0">
<StackPanel Name="MainPanel">
<StackPanel Name="ViewTaskPanel" Margin="10">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Task" Margin="0,0,10,0"/>
<StackPanel Orientation="Vertical">
<ListBox x:Name="UITasks" Width="300" Height="100" VerticalAlignment="Top" Margin="0,0,10,5"
DisplayMemberPath="Name"/>
<RadioButton x:Name="ShowAll" Content="Show All"/>
<RadioButton x:Name="ShowCompleted" Content="Show Completed" />
<RadioButton x:Name="ShowPending" Content="Show Pending"/>
</StackPanel>
<StackPanel>
<Button Content="Mark As Completed" Margin="0,0,0,5"/>
<Button Content="Mark As Pending" Margin="0,0,0,5"/>
<Button x:Name="DltTaskBtn" Content="Delete Task"
Margin="0,0,0,5" Click="DltTaskBtn_Click"/>
<Button x:Name="RenameBtn" Content="Rename" Click="RenameBtn_Click"/>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Name="AddTaskPanel" Margin="10">
<TextBlock Text="Add New Task"/>
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="Task Name" Margin="0,0,10,0"/>
<TextBox Name="TaskNameTxt" Width="260"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="AddTaskBtn" Content="Add" Margin="5" Click="AddTaskBtn_Click"/>
<Button x:Name="ClearTaskTxt" Content="Clear" Margin="5" Click="ClearTaskTxt_Click"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
</Window>
Task.cs
public class Task : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return this._Name; }
set
{
if (this._Name != value)
{
this._Name = value;
this.NotifyPropertyChanged();
}
}
}
private Status _Status;
public Status Status
{
get { return this._Status; }
set
{
if (this._Status != value)
{
this._Status = value;
this.NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propName = "")
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
public enum Status
{
Pending = 0,
Completed = 1
}
TaskSerialization.cs
public class TaskSerialization
{
public string FileName { get; set; }
public TaskSerialization(string fileName)
{
FileName = fileName;
}
/// <summary>
/// Serialize the task list to XML File
/// </summary>
/// <param name="tasks"></param>
public void SerializeTasks(List<Task> tasks)
{
StreamWriter sw = new StreamWriter(FileName);
XmlSerializer sr = new XmlSerializer(typeof(List<Task>));
sr.Serialize(sw, tasks);
sw.Close();
}
/// <summary>
/// Deserialize the taks list form XML file and return as ObservableCollection item
/// </summary>
/// <returns></returns>
public ObservableCollection<Task> DeserializeTasks()
{
XmlSerializer sr = new XmlSerializer(typeof(List<Task>));
FileStream fs = new FileStream(FileName, FileMode.Open);
return new ObservableCollection<Task>((List<Task>)sr.Deserialize(fs));
}
}
Mainwindow.cs
namespace UIToDoList_2
{
public partial class MainWindow : Window
{
private readonly string fileName = "ToDoList.xml";
private readonly TaskSerialization taskSrlz;
ObservableCollection<Task> tasks = new ObservableCollection<Task>();
public MainWindow()
{
InitializeComponent();
taskSrlz = new TaskSerialization(fileName);
tasks = taskSrlz.DeserializeTasks();
UITasks.ItemsSource = tasks;
}
private void AddTaskBtn_Click(object sender, RoutedEventArgs e)
{
AddTask();
}
private void DltTaskBtn_Click(object sender, RoutedEventArgs e)
{
DeleteTask();
}
private void AddTask()
{
var taskName = TaskNameTxt.Text;
if (!string.IsNullOrWhiteSpace(taskName))
{
tasks.Add(new Task() { Name = TaskNameTxt.Text, Status = Status.Pending });
taskSrlz.SerializeTasks(new List<Task>(tasks));
}
else
MessageBox.Show("Task name cannot be null", "Error in Task name", MessageBoxButton.OK, MessageBoxImage.Error);
}
private void DeleteTask()
{
if(UITasks.SelectedItem != null)
{
var selectedTask = (UITasks.SelectedItem as Task);
tasks.Remove(selectedTask);
taskSrlz.SerializeTasks(new List<Task>(tasks));
}
}
private void RenameBtn_Click(object sender, RoutedEventArgs e)
{
if (UITasks.SelectedItem != null)
{
(UITasks.SelectedItem as Task).Name = TaskNameTxt.Text;
taskSrlz.SerializeTasks(new List<Task>(tasks));
}
}
private void ClearTaskTxt_Click(object sender, RoutedEventArgs e)
{
TaskNameTxt.Clear();
}
}
}
I will mark this as answer based on clemens comment to look into binding into collections https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/data-binding-overview#binding-to-collections
I am developing a Windows Phone App 8.1 using a third party DrawerLayout.
My problem is when I have design the page using draweralayout. I need to pass the same layout to each other pages in my application. but when i use bold Frame.navigate(typeof(Page1)); the application is crashed.
I am unable to debug the problem.
please help!!!
My Xaml Code is
<Grid x:Name="Rootlayout">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- title bar-->
<Grid x:Name="TitleBar" Height="50" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="SkyBlue">
<Image Source="/Assets/fs-logo.png" Height="50" HorizontalAlignment="Left" Margin="10,0,0,0"/>
</Grid>
<!--Drawer Layout-->
<drawer:DrawerLayout x:Name="DrawerLayout" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<!--Main Layout-->
<Grid x:Name="mainLayout" Background="White" >
<ScrollViewer>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="mainImage" Grid.Row="0" Source="{Binding }"></Image>
<GridView x:Name="grdView" Grid.Row="1" ItemsSource="{Binding }" ItemContainerStyle="{StaticResource GridViewItemContainer}" Tapped="grdView_Tapped" >
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Blue">
<Grid Height="{Binding Size}"
Width="{Binding Size}">
<Image Height="120" Width="150" Source="{Binding sImageURL}" Stretch="Fill">
</Image>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Bottom" Foreground="Black" FontSize="18"/>
</Grid>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"></ItemsWrapGrid>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
</ScrollViewer>
</Grid>
<!--Drawer Layout-->
<Grid x:Name="listFragment" FlowDirection="LeftToRight" >
<ListView x:Name="listItem" SelectionChanged="listItem_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="20" Foreground="Black" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</drawer:DrawerLayout>
<Image Grid.Row="1" Grid.Column="0" Height="50" Width="50" Source="/Assets/appbar.right.png" Tapped="chevlon_Tapped">
</Image>
</Grid>
My MainPage.cs
public sealed partial class MainPage : Page
{
private NavigationHelper navigationHelper;
private ObservableDictionary defaultViewModel = new ObservableDictionary();
List<Services.Company> companyData;
List<Services.Category> categoryData;
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
this.navigationHelper.SaveState += this.NavigationHelper_SaveState;
this.NavigationCacheMode = NavigationCacheMode.Required;
}
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync();
// SetGridViewItemSize();
//throw new NotImplementedException();
}
/// <summary>
/// Gets the <see cref="NavigationHelper"/> associated with this <see cref="Page"/>.
/// </summary>
public NavigationHelper NavigationHelper
{
get { return this.navigationHelper; }
}
/// <summary>
/// Gets the view model for this <see cref="Page"/>.
/// This can be changed to a strongly typed view model.
/// </summary>
public ObservableDictionary DefaultViewModel
{
get { return this.defaultViewModel; }
}
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
if (e.PageState != null)
{
// this.DefaultViewModel["MainPage"] = (MainPage)e.PageState["MainPage"];
// Restore scroll offset
var index = (int)e.PageState["FirstVisibleItemIndex"];
var container = grdView.ContainerFromIndex(index);
grdView.ScrollIntoView(container);
}
else
{
//Load Data for the First time
DrawerLayout.InitializeDrawerLayout();
var company = await Services.CompCatInfo.GetCompaniesAsync(App.compId);
companyData = company.ToList();
if (companyData.Count > 0)
{
mainImage.Source = new BitmapImage(new Uri(companyData.ElementAt(0).LogoImgUrl, UriKind.Absolute));
}
var category = await Services.CompCatInfo.GetCategoriesAsync(App.compId);
categoryData = category.ToList();
SetGridViewItemSize();
if (categoryData.Count > 0)
{
grdView.ItemsSource = categoryData;
}
}
}
private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
{
var isp = (ItemsWrapGrid)grdView.ItemsPanelRoot;
int firstVisibleItem = isp.FirstVisibleIndex;
e.PageState["FirstVisibleItemIndex"] = firstVisibleItem;
// e.PageState["HomePage"] = this.Frame.CurrentSourcePageType;
// This must be serializable according to the SuspensionManager
//e.PageState["MainPage"] = this.DefaultViewModel["MainPage"];
}
private void SetGridViewItemSize()
{
//var viewModel = (DataContext as ViewModel1);
var width = Math.Truncate((grdView.ActualWidth - 10));
var height = Math.Truncate((grdView.ActualHeight - 10));
// total left + right margin for each tile (ItemContainerStyle)
var margin = 10;
var twoColumnGridPortrait = (width / 2) - margin;
// var threeColumnGridPortrait = (width / 3) - margin;
var twoColumnGridLandscape = (height / 2) - margin;
var threeColumnGridLandscape = (height / 3) - margin;
double portrait;
double landscape;
portrait = twoColumnGridPortrait;
landscape = threeColumnGridLandscape;
Application.Current.Resources["GridViewItemPortrait"] = Math.Round(portrait, 2);
Application.Current.Resources["GridViewItemLandscape"] = Math.Round(landscape, 2);
if (DisplayInformation.GetForCurrentView().CurrentOrientation == DisplayOrientations.Portrait)
{
Measure((double)Application.Current.Resources["GridViewItemPortrait"]);
}
else
{
Measure((double)Application.Current.Resources["GridViewItemLandscape"]);
}
// throw new NotImplementedException();
}
private void Measure(double size)
{
for (int i = 0; i < categoryData.Count; i++)
{
var item = categoryData[i];
item.Size = size;
}
//throw new NotImplementedException();
}
#region NavigationHelper registration
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
//if (e.NavigationMode == NavigationMode.New)
//{
// DrawerLayout.InitializeDrawerLayout();
// var company = await Services.CompCatInfo.GetCompaniesAsync(App.compId);
// companyData = company.ToList();
// if (companyData.Count > 0)
// {
// mainImage.Source = new BitmapImage(new Uri(companyData.ElementAt(0).LogoImgUrl, UriKind.Absolute));
// }
// var category = await Services.CompCatInfo.GetCategoriesAsync(App.compId);
// categoryData = category.ToList();
// SetGridViewItemSize();
// grdView.ItemsSource = categoryData;
//}
//else
//{
// // this.Frame.Content = e.Content;
//}
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedFrom(e);
}
#endregion
private void chevlon_Tapped(object sender, TappedRoutedEventArgs e)
{
string[] list = new string[] { "Services","Solutions","Technologies","About Us"};
listItem.ItemsSource = list.ToList();
if(DrawerLayout.IsDrawerOpen)
{
DrawerLayout.CloseDrawer();
}
else
{
DrawerLayout.OpenDrawer();
}
}
private void listItem_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (listItem.SelectedItem != null)
{
var selecteditem = listItem.SelectedValue as string;
// DetailsTxtBlck.Text = "SelectedItem is: " + selecteditem;
DrawerLayout.CloseDrawer();
listItem.SelectedItem = null;
}
}
private void grdView_Tapped(object sender, TappedRoutedEventArgs e)
{
DrawerLayout.CloseDrawer();
if(e.OriginalSource.GetType().ToString()=="Windows.UI.Xaml.Controls.Image"||e.OriginalSource.GetType().ToString()=="Windows.UI.Xaml.Controls.TextBlock")
{
var catObj = (sender as GridView).SelectedItem as Services.Category;
////Frame rootFrame = Window.Current.Content as Frame;
////rootFrame.Navigate(typeof(Page2),catObj);
Frame.Navigate(typeof(Page2),catObj);
}
}
}
You can navigate by this way
CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
(Window.Current.Content as Frame).Navigate(typeof(Page name));
});
I have structured the classes like this for my Universal app. Currently working in the WP8.1 part.
The following classes are put in the shared code. (Hoping to use it in Win8.1)
FolderItemViewer.xaml(UserControl) It is the DataTemplate for a ListView in the MainPage.xaml
FolderCollection class, which is the collection that is bound to the Listview in the Mainpage.xaml of the WP
Now the problem is, I have wired the manipulation events to the datatemplate grids in the FolderItemViewer.xaml to capture the right and left swipe and it is working. Now based on this, I need to update that CollectionItem in FolderCollection class and hence the ListView in Mainpage.xaml.
How do I capture that listview item or the collectionitem bound since the manipulation events lie in the FolderItemViewer class?
Can I get the listview item? Or a call back function to the listlivew item template changed? or somethin like that?
EDIT
Sorry to put in so much code. But really appreciate somebody's help in getting this right.
This is the FolderItemViewer.xaml
<UserControl
x:Class="JusWrite2.FolderItemViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:JusWrite2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="MainGrid">
<Grid Height="60" Width="380" Margin="0,0,0,1">
<Grid x:Name="ItemGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Width="380" Height="60" Background="Transparent" Canvas.ZIndex="2"
ManipulationMode="TranslateX,System" ManipulationStarted="On_ChannelItem_ManipulationStarted" ManipulationDelta="On_ChannelItem_ManipulationDelta" ManipulationCompleted="OnChannelItemManipulationCompleted">
<TextBlock x:Name="titleTextBlock" Margin="20,0,0,0" Canvas.ZIndex="2" VerticalAlignment="Center" TextAlignment="Left" FontSize="25" >
</TextBlock>
</Grid>
<Grid x:Name="DelGrid" Opacity="0.0" HorizontalAlignment="Right" VerticalAlignment="Center" Height="60" Background="Red" Canvas.ZIndex="-1" Tapped="On_ChannelDelete_Tap" Width="380">
<Button Content="X" FontSize="25" Canvas.ZIndex="-1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="380" BorderThickness="0" />
</Grid>
</Grid>
</Grid>
</UserControl>
code behind
private void OnChannelItemManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
Grid ChannelGrid = (Grid)sender;
Grid mGrid = (Grid)(ChannelGrid.Parent);
Grid DeleteGrid = (Grid)((Grid)(ChannelGrid.Parent)).Children[1];
FolderCollection swipedItem = ChannelGrid.DataContext as FolderCollection;// grid has null value for datacontext
double dist = e.Cumulative.Translation.X;
if (dist < -100)
{
// Swipe left
}
else
{
// Swipe right
}
}
FolderCollection.xaml has two classes in it. FolderItem and FolderCollection
public class FolderItem : INotifyPropertyChanged
{
// variables
public FolderItem()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public int CompletionStatus
{
//code
}
public int Priority
{
//code
}
public string FolderText
{
//code
}
public int PenColor
{
//code
}
public string UUID
{
//code
}
public string CreateUUID()
{
//code
}
}
public class FolderCollection : IEnumerable<Object>
{
private ObservableCollection<FolderItem> folderCollection = new ObservableCollection<FolderItem>();
private static readonly FolderCollection instance = new FolderCollection();
public static FolderCollection Instance
{
get
{
return instance;
}
}
public IEnumerator<Object> GetEnumerator()
{
return folderCollection.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(FolderItem fItem)
{
folderCollection.Add(fItem);
}
public ObservableCollection<FolderItem> FolderCollectionInstance
{
get
{
return folderCollection;
}
}
}
And this is the MainPage.xaml where I have data bound.
// Resources
<DataTemplate x:Key="StoreFrontTileTemplate">
<local:FolderItemViewer />
</DataTemplate>
<ListView x:Name="FolderListView" ItemsSource="{Binding}"
SelectionMode="None"
ItemTemplate="{StaticResource StoreFrontTileTemplate}"
ContainerContentChanging="ItemListView_ContainerContentChanging">
</ListView>
code behind
//Constructor
FolderListView.DataContext = fc.FolderCollectionInstance;
FolderListView.ItemsSource = fc.FolderCollectionInstance;
private void ItemListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
FolderItemViewer iv = args.ItemContainer.ContentTemplateRoot as FolderItemViewer;
if (args.InRecycleQueue == true)
{
iv.ClearData();
}
else if (args.Phase == 0)
{
iv.ShowPlaceholder(args.Item as FolderItem);
// Register for async callback to visualize Title asynchronously
args.RegisterUpdateCallback(ContainerContentChangingDelegate);
}
else if (args.Phase == 1)
{
iv.ShowTitle();
args.RegisterUpdateCallback(ContainerContentChangingDelegate);
}
else if (args.Phase == 2)
{
//iv.ShowCategory();
//iv.ShowImage();
}
// For imporved performance, set Handled to true since app is visualizing the data item
args.Handled = true;
}
private TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs> ContainerContentChangingDelegate
{
get
{
if (_delegate == null)
{
_delegate = new TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs>(ItemListView_ContainerContentChanging);
}
return _delegate;
}
}
private TypedEventHandler<ListViewBase, ContainerContentChangingEventArgs> _delegate;
The list item should be available as the data context of the grid: ChannelGrid.DataContext.
I am creating a to do list application. At the moment I want to add a new to do list from todolistPage.xaml and after adding, I want to take the data to be able to view in the MainPage.xaml . I am able to view it from the todolistPage but not sure how to bring it to to another page. Hope to have some help. Thanks.
Below are my codes
MainPage.xaml.cs
namespace PivotApp3
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Set the data context of the listbox control to the sample data
DataContext = App.ViewModel;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
// Load data for the ViewModel Items
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
}
private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var si = mLongListSelector.SelectedItem as PivotApp3.ViewModels.ItemViewModel;
if (mLongListSelector.SelectedItem == null)
return;
if (si.LineOne.Equals("+ To Do List"))
NavigationService.Navigate(new Uri("/todolistPage.xaml", UriKind.Relative));
else if (si.LineOne.Equals("+ Reminder"))
NavigationService.Navigate(new Uri("/reminderPage.xaml", UriKind.Relative));
// Reset selected item to null (no selection)
mLongListSelector.SelectedItem = null;
}
}
MainPage.xaml
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!-- LOCALIZATION NOTE:
To localize the displayed strings copy their values to appropriately named
keys in the app's neutral language resource file (AppResources.resx) then
replace the hard-coded text value between the attributes' quotation marks
with the binding clause whose path points to that string name.
For example:
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
This binding points to the template's string resource named "ApplicationTitle".
Adding supported languages in the Project Properties tab will create a
new resx file per language that can carry the translated values of your
UI strings. The binding in these examples will cause the value of the
attributes to be drawn from the .resx file that matches the
CurrentUICulture of the app at run time.
-->
<!--Pivot Control-->
<phone:Pivot Title="DAILY ROUTINE">
<!--Pivot item one-->
<phone:PivotItem Header="activity">
<!--Double line list with text wrapping-->
<phone:LongListSelector x:Name="mLongListSelector" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="LongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</phone:PivotItem>
<!--Pivot item two-->
<phone:PivotItem Header="today">
</phone:PivotItem>
</phone:Pivot>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" IsHitTestVisible="False" />-->
</Grid>
todolistPage.xaml.cs
namespace PivotApp3
{
public partial class todolistPage : PhoneApplicationPage, INotifyPropertyChanged
{
// Data context for the local database
private ToDoDataContext toDoDB;
// Define an observable collection property that controls can bind to.
private ObservableCollection<ToDoItem> _toDoItems;
public ObservableCollection<ToDoItem> ToDoItems
{
get
{
return _toDoItems;
}
set
{
if (_toDoItems != value)
{
_toDoItems = value;
NotifyPropertyChanged("ToDoItems");
}
}
}
//constructor
public todolistPage()
{
InitializeComponent();
// Connect to the database and instantiate data context.
toDoDB = new ToDoDataContext(ToDoDataContext.DBConnectionString);
// Data context and observable collection are children of the main page.
this.DataContext = this;
}
private void deleteTaskButton_Click(object sender, RoutedEventArgs e)
{
// Cast parameter as a button.
var button = sender as Button;
if (button != null)
{
// Get a handle for the to-do item bound to the button.
ToDoItem toDoForDelete = button.DataContext as ToDoItem;
// Remove the to-do item from the observable collection.
ToDoItems.Remove(toDoForDelete);
// Remove the to-do item from the local database.
toDoDB.ToDoItems.DeleteOnSubmit(toDoForDelete);
// Save changes to the database.
toDoDB.SubmitChanges();
// Put the focus back to the main page.
this.Focus();
}
}
private void newToDoTextBox_GotFocus(object sender, RoutedEventArgs e)
{
// Clear the text box when it gets focus.
newToDoTextBox.Text = String.Empty;
}
private void newToDoAddButton_Click(object sender, RoutedEventArgs e)
{
// Create a new to-do item based on the text box.
ToDoItem newToDo = new ToDoItem { ItemName = newToDoTextBox.Text };
// Add a to-do item to the observable collection.
ToDoItems.Add(newToDo);
// Add a to-do item to the local database.
toDoDB.ToDoItems.InsertOnSubmit(newToDo);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
// Call the base method.
base.OnNavigatedFrom(e);
// Save changes to the database.
toDoDB.SubmitChanges();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
// Define the query to gather all of the to-do items.
var toDoItemsInDB = from ToDoItem todo in toDoDB.ToDoItems
select todo;
// Execute the query and place the results into a collection.
ToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
// Call the base method.
base.OnNavigatedTo(e);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify the app that a property has changed.
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
public class ToDoDataContext : DataContext
{
// Specify the connection string as a static, used in main page and app.xaml.
public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";
// Pass the connection string to the base class.
public ToDoDataContext(string connectionString)
: base(connectionString)
{ }
// Specify a single table for the to-do items.
public Table<ToDoItem> ToDoItems;
}
[Table]
public class ToDoItem : INotifyPropertyChanged, INotifyPropertyChanging
{
// Define ID: private field, public property and database column.
private int _toDoItemId;
[Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
public int ToDoItemId
{
get
{
return _toDoItemId;
}
set
{
if (_toDoItemId != value)
{
NotifyPropertyChanging("ToDoItemId");
_toDoItemId = value;
NotifyPropertyChanged("ToDoItemId");
}
}
}
// Define item name: private field, public property and database column.
private string _itemName;
[Column]
public string ItemName
{
get
{
return _itemName;
}
set
{
if (_itemName != value)
{
NotifyPropertyChanging("ItemName");
_itemName = value;
NotifyPropertyChanged("ItemName");
}
}
}
// Define completion value: private field, public property and database column.
private bool _isComplete;
[Column]
public bool IsComplete
{
get
{
return _isComplete;
}
set
{
if (_isComplete != value)
{
NotifyPropertyChanging("IsComplete");
_isComplete = value;
NotifyPropertyChanged("IsComplete");
}
}
}
// Version column aids update performance.
[Column(IsVersion = true)]
private Binary _version;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Used to notify the page that a data context property changed
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region INotifyPropertyChanging Members
public event PropertyChangingEventHandler PropertyChanging;
// Used to notify the data context that a data context property is about to change
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
#endregion
}
todolistPage.xaml
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="TO DO LIST" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="add" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!-- Bind the list box to the observable collection. -->
<ListBox x:Name="toDoItemsListBox" ItemsSource="{Binding ToDoItems}"
Grid.Row="1" Margin="12,0,28,210" Width="440">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Width="440">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<CheckBox
IsChecked="{Binding IsComplete, Mode=TwoWay}"
Grid.Column="0"
VerticalAlignment="Center"/>
<TextBlock
Text="{Binding ItemName}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1"
VerticalAlignment="Center"/>
<Button
Grid.Column="2"
x:Name="deleteTaskButton"
BorderThickness="0"
Margin="0"
Click="deleteTaskButton_Click">
<Image Source="appbar.delete.rest.png"/>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="2" Margin="12,465,12,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<TextBox
x:Name="newToDoTextBox"
Grid.Column="0"
Text="add new task"
FontFamily="{StaticResource PhoneFontFamilyLight}"
GotFocus="newToDoTextBox_GotFocus" Margin="0,-65,0,104" Grid.ColumnSpan="2"/>
<Button
Content="add"
x:Name="newToDoAddButton"
Click="newToDoAddButton_Click" Margin="150,43,130,10" Grid.ColumnSpan="2"/>
</Grid>
</Grid>
Database Created
using (ToDoDataContext db = new ToDoDataContext(ToDoDataContext.DBConnectionString))
{
if (db.DatabaseExists() == false)
{
//Create the database
db.CreateDatabase();
}
}
Put your database into App.xaml.cs:
// Data context for the local database
public ToDoDataContext toDoDB;
add this code to App.xaml.cs:
public new static App Current
{
get
{
return (App)Application.Current;
}
}
Then you can access your database everywhere by using:
App.Current.toDoDB...
You can create class to manipulate data in sql and make it avaiable from App.xaml.cs
Here is sample code
ToDoDataViewModel class:
public class ToDoDataViewModel : INotifyPropertyChanged
{
ToDoDataContext db;
public ToDoDataViewModel(string connectionString)
{
db = new ToDoDataContext(connectionString);
}
private ObservableCollection<ToDoItem> _toDoItems;
public ObservableCollection<ToDoItem> ToDoItems
{
get { return this._toDoItems; }
set
{
this._toDoItems = value;
NotifyPropertyChanged("ToDoItems");
}
}
public void LoadCollectionsFromDatabase()
{
var toDos = from todo in db.ToDoItems
select todo;
_toDoItems = new ObservableCollection<ToDoItem>(toDos);
}
public void InsertToDoItem(ToDoItem item)
{
db.ToDoItems.InsertOnSubmit(item);
_toDoItems.Add(item);
db.SubmitChanges();
}
public void DeleteToDoItem(ToDoItem item)
{
db.ToDoItems.DeleteOnSubmit(item);
_toDoItems.Remove(item);
db.SubmitChanges();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
In App.xaml.cs:
public partial class App : Application
{
private static ToDoDataViewModel _viewModel;
public static ToDoDataViewModel ViewModel
{
get { return _viewModel; }
}
//other methods of App
public App()
{
//place this code at the and of the contructor
CreateDb();
}
private void CreateDb()
{
using(var db=new ToDoDataContext(ToDoDataContext.DBConnectionString))
{
if(!db.DatabaseExists())
{
db.CreateDatabase();
}
}
_viewModel=new ToDoDataViewModel(ToDoDataContext.DBConnectionString);
_viewModel.LoadCollectionsFromDatabase();
}
}
And place this code in the constructors of your pages:
this.DataContext=App.ViewModel;
This way you separated your database logic from application logic
Now you can update your newToDoAddButton_Click method as following:
private void newToDoAddButton_Click(object sender, RoutedEventArgs e)
{
// Create a new to-do item based on the text box.
ToDoItem newToDo = new ToDoItem { ItemName = newToDoTextBox.Text };
//Add to-do item to the local database
App.ViewModel.InsertToDoItem(newToDo);
this.Focus();
}
And your deleteTaskButton_Click method:
private void deleteTaskButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
if (button != null)
{
// Get a handle for the to-do item bound to the button.
ToDoItem toDoForDelete = button.DataContext as ToDoItem;
// Remove the to-do item from the local database.
App.ViewModel.DeleteToDoItem(toDoForDelete);
this.Focus();
}
}