Using SQLite-net-pcl and can't update the data - sqlite

So i have this really annoying problem where i Can't seem to get it to update any of the databases i have created, whats worse the i can see the instance is showing the updated information but isn't applying it. I'm really new to this and is my first course project.
This is the code that is being used to update the data:
'''
using Project.Database;
using Project.DataClasses;
using Project.Pages.SuperPages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Project.Pages.UpdateDeleteListItem
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class UpdateDeleteList : ContentPage
{
private new readonly Label Title;
private Style LabelStyle;
private StoreDetails UpdateStoreDetails;
private Entry SNum;
private Entry SName;
private Entry SMName;
private Entry Addy;
public UpdateDeleteList(string pageType, object Item)
{
InitializeComponent();
BindingContext = Item;
UpdateStoreDetails = (StoreDetails)Item;
SetLabelStyle();
string titleMsg = "Update or Delete Selected " + pageType;
Frame frame = new Frame();
Label title = new Label() {Text = titleMsg };
Title = title;
StackLayout titleStack = new StackLayout() { Children = { Title } };
frame.Content = titleStack;
if (pageType == "Store")
{
StoreUDLItem(frame);
}
if (pageType == "Ticket")
{
TicketUDLItem(frame);
}
StylePage();
}
private void SaveButton_Clicked(object sender, EventArgs args)
{
if (StoreCheckValues() == true)
{
var store = SName;
var storeManager = SMName;
var storeNumber = SNum;
var address = Addy;
var storeDataAccess = new StoreDataAccess();
UpdateStoreDetails.StoreName = store.Text;
UpdateStoreDetails.StoreManger = storeManager.Text;
UpdateStoreDetails.StoreNumber = storeNumber.Text;
UpdateStoreDetails.Address = address.Text;
//MerchandiserKey = GetMerchId()
storeDataAccess.SaveStoreDetails(UpdateStoreDetails);
storeDataAccess.SaveAllStoreDetails();
}
'''
here is the data access methods:
'''
using Project.DataClasses;
using SQLite;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using Xamarin.Forms;
namespace Project.Database
{
class StoreDataAccess
{
private SQLiteConnection database;
private static object collisionLock = new object();
public ObservableCollection<StoreDetails> StoreDetails { get; set; }
public StoreDataAccess()
{
database = DependencyService.Get<IDatabaseConnection>().DbConnectionStore();
database.CreateTable<StoreDetails>();
this.StoreDetails = new ObservableCollection<StoreDetails>(database.Table<StoreDetails>());
//AddNewTicket(new Ticket ticket);
}
//add ticket method
public void AddNewStore(StoreDetails item)
{
this.StoreDetails.Add(item);
}
//retrieve ticket method
public StoreDetails GetStoreDetails(int id)
{
lock (collisionLock)
{
return database.Table<StoreDetails>().FirstOrDefault(StoreDetails => StoreDetails.StoreId == id);
}
}
//save ticket
public int SaveStoreDetails(StoreDetails storeDetailsInstance)
{
lock (collisionLock)
{
if (storeDetailsInstance.StoreId != 0)
{
database.Update(storeDetailsInstance);
return storeDetailsInstance.StoreId;
}
else
{
database.Insert(storeDetailsInstance);
return storeDetailsInstance.StoreId;
}
//database.Commit();
}
}
public void SaveAllStoreDetails()
{
lock (collisionLock)
{
foreach (var storeDetailsInstance in this.StoreDetails)
{
if (storeDetailsInstance.StoreId != 0)
{
database.Update(storeDetailsInstance);
}
else
{
database.Insert(storeDetailsInstance);
}
}
}
}
'''
This is the page that is sending the information to the first code block to bind the data too
'''
using Project.Database;
using Project.DataClasses;
using Project.Pages.UpdateDeleteListItem;
using SQLite;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Project.Pages.ListPages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StoreList : ContentPage
{
private ObservableCollection<StoreDetails> Items { get; set; }
private readonly StoreDataAccess storeDataAccess;
private readonly SQLiteConnection database;
public StoreList()
{
InitializeComponent();
storeDataAccess = new StoreDataAccess();
this.BindingContext = this.storeDataAccess;
Items = storeDataAccess.StoreDetails;
StoreView.ItemsSource = Items;
}
async void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
{
if (e.Item == null) { return; }
else
{
//var id = Items[e.ItemIndex].StoreId;
await Navigation.PushAsync(new UpdateDeleteList("Store", e.Item));
//Deselect Item
((ListView)sender).SelectedItem = null;
}
}
//page reload handle
protected override void OnAppearing()
{
base.OnAppearing();
var dbName = "StoreListDatabase.db3";
var path = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.Personal), dbName);
if (database == null)
{
new StoreDataAccess();
}
using (SQLiteConnection conn = new SQLiteConnection(path))
{
Items = storeDataAccess.StoreDetails;
StoreView.ItemsSource = Items;
}
}
}
}
'''
and lastly here is my databbase model for it:
'''
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
using SQLite;
using System.ComponentModel;
namespace Project.DataClasses
{
class StoreDetails : INotifyPropertyChanged
{
private int _storeId;
[PrimaryKey, AutoIncrement, NotNull]
public int StoreId
{
get { return _storeId; }
set { _storeId = value; OnPropertyChanged(nameof(StoreId)); }
}
private string _storeName;
[NotNull, DefaultValue("Enter Store Name")]
public string StoreName
{
get { return _storeName; }
set { _storeName = value; OnPropertyChanged(nameof(_storeName)); }
}
private string _storeManger;
[NotNull, DefaultValue("Enter Store Managers Name")]
public string StoreManger
{
get { return _storeManger; }
set { _storeManger = value; OnPropertyChanged(nameof(StoreManger)); }
}
private string _storeNumber;
[NotNull, DefaultValue("Enter Store Number")]
public string StoreNumber
{
get { return _storeNumber; }
set { _storeNumber = value; OnPropertyChanged(nameof(StoreNumber)); }
}
private string _address;
[NotNull, DefaultValue("Enter Address")]
public string Address
{
get { return _address; }
set { _address = value; OnPropertyChanged(nameof(Address)); }
}
private int _merchandiserKey;
[NotNull]
public int MerchandiserKey
{
get { return _merchandiserKey; }
set { _merchandiserKey = value; OnPropertyChanged(nameof(MerchandiserKey)); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
'''
any help would be greatly appreciated
'''
public int SaveStoreDetails(StoreDetails storeDetailsInstance)
{
lock (collisionLock)
{
if (storeDetailsInstance.StoreId != 0)
{
database.Update(storeDetailsInstance);
return storeDetailsInstance.StoreId;
}
else
{
database.Insert(storeDetailsInstance);
return storeDetailsInstance.StoreId;
}
//database.Commit();
}
}
'''
this is the area where it all seems to be going wrong i just don't know why
Thank You Jason, you were correct in that the error was in calling both the savefunctions and overwriting it!!

Related

xamarin forms Tabbed page title no wrap

i have tabbed page with number of pages , the issue here that the title of the page is not appearing well, it need to be no wrap or expand to fit the text.
any suggestion to solve this issue.
You Need to create one TabbedPageRenderer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android.AppCompat;
using AppTab.Droid;
using Android.Support.V4.View;
using Android.Support.Design.Widget;
using System.ComponentModel;
using Xamarin.Forms.Platform.Android;
using AppTab;
using Android.Graphics.Drawables;
using Android.Graphics;
[assembly: ExportRenderer(typeof(CustomTabbedPage), typeof(ScrollableTabbedPage))]
namespace AppTab.Droid
{
public class ScrollableTabbedPage : TabbedPageRenderer
{
public override void OnViewAdded(Android.Views.View child)
{
base.OnViewAdded(child);
var tabLayout = child as TabLayout;
if (tabLayout != null)
{
tabLayout.TabMode = TabLayout.ModeScrollable;
}
}
public static void Init()
{
var unused = DateTime.UtcNow;
}
private CustomTabbedPage FormsTabbedPage => Element as CustomTabbedPage;
private Android.Graphics.Color _selectedColor = Android.Graphics.Color.Black;
private static readonly Android.Graphics.Color DefaultUnselectedColor = Xamarin.Forms.Color.Gray.ToAndroid();
private static Android.Graphics.Color _barBackgroundDefault;
private Android.Graphics.Color _unselectedColor = DefaultUnselectedColor;
ViewPager _viewPager;
TabLayout _tabLayout;
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
// Get tabs
for (var i = 0; i < ChildCount; i++)
{
var v = GetChildAt(i);
var pager = v as ViewPager;
if (pager != null)
_viewPager = pager;
else if (v is TabLayout)
_tabLayout = (TabLayout)v;
}
if (e.OldElement != null)
{
_tabLayout.TabSelected -= TabLayout_TabSelected;
_tabLayout.TabUnselected -= TabLayout_TabUnselected;
}
if (e.NewElement != null)
{
_barBackgroundDefault = (_tabLayout.Background as ColorDrawable)?.Color ??
Android.Graphics.Color.Blue;
SetSelectedColor();
SetBarBackgroundColor();
_tabLayout.TabSelected += TabLayout_TabSelected;
_tabLayout.TabUnselected += TabLayout_TabUnselected;
SetupTabColors();
SelectTab(0);
}
}
void SelectTab(int position)
{
if (_tabLayout.TabCount > position)
{
_tabLayout.GetTabAt(position).Icon?
.SetColorFilter(_selectedColor, PorterDuff.Mode.SrcIn);
_tabLayout.GetTabAt(position).Select();
}
else
{
throw new IndexOutOfRangeException();
}
}
void SetupTabColors()
{
_tabLayout.SetSelectedTabIndicatorColor(_selectedColor);
_tabLayout.SetTabTextColors(_unselectedColor, _selectedColor);
for (int i = 0; i < _tabLayout.TabCount; i++)
{
var tab = _tabLayout.GetTabAt(i);
tab.Icon?.SetColorFilter(_unselectedColor, PorterDuff.Mode.SrcIn);
}
}
private void TabLayout_TabUnselected(object sender, TabLayout.TabUnselectedEventArgs e)
{
var tab = e.Tab;
tab.Icon?.SetColorFilter(_unselectedColor, PorterDuff.Mode.SrcIn);
}
private void TabLayout_TabSelected(object sender, TabLayout.TabSelectedEventArgs e)
{
var tab = e.Tab;
_viewPager.CurrentItem = tab.Position;
tab.Icon?.SetColorFilter(_selectedColor, PorterDuff.Mode.SrcIn);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
int lastPosition = _tabLayout.SelectedTabPosition;
switch (e.PropertyName)
{
case nameof(CustomTabbedPage.BarBackgroundColor):
case nameof(CustomTabbedPage.BarBackgroundApplyTo):
SetBarBackgroundColor();
SetupTabColors();
SelectTab(lastPosition);
break;
case nameof(CustomTabbedPage.SelectedColor):
SetSelectedColor();
SetupTabColors();
SelectTab(lastPosition);
break;
default:
base.OnElementPropertyChanged(sender, e);
break;
}
}
private void SetSelectedColor()
{
if (FormsTabbedPage.SelectedColor != default(Xamarin.Forms.Color))
_selectedColor = FormsTabbedPage.SelectedColor.ToAndroid();
}
private void SetBarBackgroundColor()
{
if (FormsTabbedPage.BarBackgroundApplyTo.HasFlag(BarBackgroundApplyTo.Android))
{
_tabLayout.SetBackgroundColor(FormsTabbedPage.BarBackgroundColor.ToAndroid());
_unselectedColor = FormsTabbedPage.BarBackgroundColor != default(Xamarin.Forms.Color)
? FormsTabbedPage.BarBackgroundColor.ToAndroid()
: DefaultUnselectedColor;
}
else
{
_tabLayout.SetBackgroundColor(_barBackgroundDefault);
_unselectedColor = DefaultUnselectedColor;
}
}
}
}
Second you Need CustomTabbedPage class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace AppTab
{
[Flags]
public enum BarBackgroundApplyTo
{
None = 0x01,
Android = 0x10,
iOS = 0x100
}
public class CustomTabbedPage : TabbedPage
{
public CustomTabbedPage()
{
}
public static readonly BindableProperty SelectedColorProperty =
BindableProperty.Create(nameof(SelectedColor), typeof(Color), typeof(CustomTabbedPage), default(Color));
public Color SelectedColor
{
get => (Color)GetValue(SelectedColorProperty);
set => SetValue(SelectedColorProperty, value);
}
public static readonly BindableProperty BarBackgroundApplyToProperty =
BindableProperty.Create(nameof(BarBackgroundApplyTo), typeof(BarBackgroundApplyTo), typeof(CustomTabbedPage), BarBackgroundApplyTo.Android);
public BarBackgroundApplyTo BarBackgroundApplyTo
{
get => (BarBackgroundApplyTo)GetValue(BarBackgroundApplyToProperty);
set => SetValue(BarBackgroundApplyToProperty, value);
}
public new static readonly BindableProperty BarBackgroundColorProperty =
BindableProperty.Create(nameof(BarBackgroundColor), typeof(Color), typeof(CustomTabbedPage), default(Color));
public new Color BarBackgroundColor
{
get => (Color)GetValue(BarBackgroundColorProperty);
set => SetValue(BarBackgroundColorProperty, value);
}
}
}
And Third You Need CustomMain Page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace AppTab
{
public class CustomMain : CustomTabbedPage
{
public CustomMain()
{
BarBackgroundApplyTo = BarBackgroundApplyTo.Android;
//BarBackgroundColor = Color.Red;
Children.Add(new abc() { Title = "ABC"});
Children.Add(new xyz() { Title = "XYZ" });
Children.Add(new pqr() { Title = "PQR" });
Children.Add(new str() { Title = "STR" });
Children.Add(new ftx() { Title = "FTX" });
Children.Add(new dtb() { Title = "DTB" });
}
}
}
Click here for ScreenShot
In Resources->Layout->Tabbar.xml set tabMode to "scrollable".
It should work.

Supporting nested elements in ASP.Net Custom Server Controls

I want to create a custom server control which looks like this:
<cc:MyControl prop1="a" prop2="b">
<cc:MyItem name="xxx">
<cc:MyItem name="yyy">
<cc:MyItem name="zzz">
</cc:MyControl>
MyControl is of course implemented as a server control, however I do not want MyItem to be child controls. Rather they should exist as simple .Net objects. I have a class called MyItem, and the control has a property called Items, and when MyItem elements are declared in the markup, the objects should be instantiated and added to the collection.
The tutorials on MSDN don't actually explain how this happens. See: http://msdn.microsoft.com/en-us/library/9txe1d4x.aspx
I'd like to know:
How is <cc:MyItem> mapped to the MyItem class? Does the element in the markup have to have the same name as the object's class?
Which constructor of MyItem is called when MyItems are added declaratively, and when?
What collection types am I permitted to use to hold MyItem objects? The link above uses ArrayList, but can I use the strongly typed List instead?
Is it possible for a control to contain multiple collections?
It is so common to use class name for markup, but you can assign another name if you want, I do not explain more, if you want please comment
when asp.net compiles markup, it uses default parameter less constructor
you can use any collection type but if you want to use benefits of viewstate your collection type must implement IStateManager interface (below I wrote source of collection that I created for my self with state managing support)
Yes, your control can have multiple collections, just add required attributes as below:
(I used one of my codes, please replace names with your desired name)
if you want to have collection first of all you must define its property in your control.
imagine we have a control named CustomControl that extends Control as below:
[System.Web.UI.ParseChildrenAttribute(true)]
[System.Web.UI.PersistChildrenAttribute(false)]
public class CustomControl : Control{
private GraphCollection m_graphs;
[Bindable(false)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public GraphCollection Graphs
{
get
{
if (this.m_graphs == null) {
this.m_graphs = new GraphCollection();
if (base.IsTrackingViewState) {
this.m_graphs.TrackViewState();
}
}
return this.m_graphs;
}
}
}
as you can see in above code, CustomControl has a field with name "m_graphs" with type of "GraphCollection", also a property that exposes this field
also please please pay attention to its attribute PersistenceMode that says to asp.net property "Graphs" must persisted as InnerProperty
also please pay attention to two attributes applied to CustomControl class
attribute ParseChildrenAttribute says to asp.net that nested markup, must be treated as properties and attribute PersistChildrenAttribute says to asp.net that nested markups are not control's children
at the final, I bring two source codes for state managing components
first of all GraphCollection that extends from StateManagedCollection (both classes was written by me)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
namespace Farayan.Web.Core
{
public class StateManagedCollection<T> : IList, ICollection, IEnumerable, IEnumerable<T>, IStateManager
where T : class, IStateManager, new()
{
// Fields
private List<T> listItems = new List<T>();
private bool marked = false;
private bool saveAll = false;
// Methods
public void Add(T item)
{
this.listItems.Add(item);
if (this.marked) {
//item.Dirty = true;
}
}
public void AddRange(T[] items)
{
if (items == null) {
throw new ArgumentNullException("items");
}
foreach (T item in items) {
this.Add(item);
}
}
public void Clear()
{
this.listItems.Clear();
if (this.marked) {
this.saveAll = true;
}
}
public bool Contains(T item)
{
return this.listItems.Contains(item);
}
public void CopyTo(Array array, int index)
{
this.listItems.CopyTo(array.Cast<T>().ToArray(), index);
}
public IEnumerator GetEnumerator()
{
return this.listItems.GetEnumerator();
}
public int IndexOf(T item)
{
return this.listItems.IndexOf(item);
}
public void Insert(int index, T item)
{
this.listItems.Insert(index, item);
if (this.marked) {
this.saveAll = true;
}
}
public void LoadViewState(object state)
{
object[] states = state as object[];
if (state == null || states.Length == 0)
return;
for (int i = 0; i < states.Length; i++) {
object itemState = states[i];
if (i < Count) {
T day = (T)listItems[i];
((IStateManager)day).LoadViewState(itemState);
} else {
T day = new T();
((IStateManager)day).LoadViewState(itemState);
listItems.Add(day);
}
}
}
public void Remove(T item)
{
int index = this.IndexOf(item);
if (index >= 0)
this.RemoveAt(index);
}
public void RemoveAt(int index)
{
this.listItems.RemoveAt(index);
if (this.marked) {
this.saveAll = true;
}
}
public object SaveViewState()
{
List<object> state = new List<object>(Count);
foreach (T day in listItems)
state.Add(((IStateManager)day).SaveViewState());
return state.ToArray();
}
int IList.Add(object item)
{
T item2 = (T)item;
this.listItems.Add(item2);
return listItems.Count - 1;
}
bool IList.Contains(object item)
{
return this.Contains((T)item);
}
int IList.IndexOf(object item)
{
return this.IndexOf((T)item);
}
void IList.Insert(int index, object item)
{
this.Insert(index, (T)item);
}
void IList.Remove(object item)
{
this.Remove((T)item);
}
void IStateManager.LoadViewState(object state)
{
this.LoadViewState(state);
}
object IStateManager.SaveViewState()
{
return this.SaveViewState();
}
void IStateManager.TrackViewState()
{
this.TrackViewState();
}
public void TrackViewState()
{
this.marked = true;
for (int i = 0; i < this.Count; i++) {
((IStateManager)this[i]).TrackViewState();
}
}
// Properties
public int Capacity
{
get
{
return this.listItems.Capacity;
}
set
{
this.listItems.Capacity = value;
}
}
public int Count
{
get
{
return this.listItems.Count;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public bool IsSynchronized
{
get
{
return false;
}
}
public T this[int index]
{
get
{
return (T)this.listItems[index];
}
}
public object SyncRoot
{
get
{
return this;
}
}
bool IList.IsFixedSize
{
get
{
return false;
}
}
object IList.this[int index]
{
get
{
return this.listItems[index];
}
set
{
this.listItems[index] = (T)value;
}
}
bool IStateManager.IsTrackingViewState
{
get
{
return this.marked;
}
}
#region IEnumerable<T> Members
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.listItems.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
and GraphCollection
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Farayan.Web.Core;
namespace Farayan.Web.AmCharts
{
public class GraphCollection : StateManagedCollection<Graph>
{
}
}
and finally Graph in our example:
using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Web.UI;
using System.ComponentModel;
using Farayan.Web.AmCharts;
using System.Collections.Generic;
using Farayan.Web.Controls;
using System.Runtime;
using Farayan.Web.Core;
namespace Farayan.Web.AmCharts
{
public class Graph : StateManager
{
#region Colorize Property
[Browsable(true)]
[Localizable(false)]
[PersistenceMode(PersistenceMode.Attribute)]
[DefaultValue(false)]
public virtual bool Colorize
{
get { return ViewState["Colorize"] == null ? false : (bool)ViewState["Colorize"]; }
set { ViewState["Colorize"] = value; }
}
#endregion
//==============================
public override void LoadViewState(object state)
{
base.LoadViewState(state);
}
public override object SaveViewState()
{
return base.SaveViewState();
}
}
}
you may noticed that Graph extends StateManager class
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web.UI;
using Farayan.Web.AmCharts;
namespace Farayan.Web.AmCharts
{
public class StateManager : IStateManager
{
protected StateBag ViewState = new StateBag();
#region IStateManager Members
public virtual bool IsTrackingViewState
{
get { return true; }
}
public virtual void LoadViewState(object state)
{
if (state != null) {
ArrayList arrayList = (ArrayList)state;
for (int i = 0; i < arrayList.Count; i += 2) {
string value = ((IndexedString)arrayList[i]).Value;
object value2 = arrayList[i + 1];
ViewState.Add(value, value2);
}
}
}
public virtual object SaveViewState()
{
ArrayList arrayList = new ArrayList();
if (this.ViewState.Count != 0) {
IDictionaryEnumerator enumerator = this.ViewState.GetEnumerator();
while (enumerator.MoveNext()) {
StateItem stateItem = (StateItem)enumerator.Value;
//if (stateItem.IsDirty) {
if (arrayList == null) {
arrayList = new ArrayList();
}
arrayList.Add(new IndexedString((string)enumerator.Key));
arrayList.Add(stateItem.Value);
//}
}
}
return arrayList;
}
public virtual void TrackViewState()
{
}
#endregion
#region IStateManager Members
bool IStateManager.IsTrackingViewState
{
get { return this.IsTrackingViewState; }
}
void IStateManager.LoadViewState(object state)
{
this.LoadViewState(state);
}
object IStateManager.SaveViewState()
{
return this.SaveViewState();
}
void IStateManager.TrackViewState()
{
this.TrackViewState();
}
#endregion
}
}

How to access datagrid in View from ViewModel in Silverlight?

Hai i'm doing one silverlight app that uses MVVM architecture.
The Scenario is this. I have one combobox and datagrid in same page.
I have use ObservableCollection to bind the values in Datagrid and in that collection i have three fields namely Fname,Sname and Dept.
I bind Dept in Combobox but if i select any one of department means that value does not update in DataGrid. ie., i have created the code in ViewModel and i use LINQ query and i have Fetched the value also in,
var semp = from s in Employees where s.Dept.Equals(Names.Dept) select s;
i need to send this semp datasource to Datagrid in View.
Datagrid Syntax is :
<my:DataGrid x:Name="McDataGrid" ItemsSource="{Binding Employees,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="130,151,0,0" Height="137" VerticalAlignment="Top" RowBackground="#AA5D9324" AutoGenerateColumns="True" HorizontalAlignment="Left" Width="196">
</my:DataGrid>
Help me if u Know...
This is the ViewModel Code:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Silverlight_MVVM.Model;
using Silverlight_MVVM.Utils;
using System.Linq;
using System.Collections.Generic;
namespace Silverlight_MVVM.ViewModel
{
public class EmployeeListViewModel:INotifyPropertyChanged
{
public ObservableCollection<Employee> Employees { get; private set; }
public EmployeeListViewModel()
{
Employees = Silverlight_MVVM.DataHelper.EmployeeDataHelper.EmployeeData ();
}
private string _fname;
public string Fname
{
get
{
return _fname;
}
set
{
_fname = value;
RaisePropertyChanged("Fname");
}
}
private string _sname;
public string Sname
{
get
{
return _sname;
}
set
{
_sname = value;
RaisePropertyChanged("Sname");
}
}
private string _dept;
public string Dept
{
get
{
return _dept;
}
set
{
_dept = value;
RaisePropertyChanged("Dept");
}
}
private Employee _SelectedEmployee;
public Employee SelectedEmployee
{
get
{
return _SelectedEmployee;
}
set
{
_SelectedEmployee = value;
RaisePropertyChanged("SelectedEmployee");
}
}
private string _demp;
public string demp
{
get
{
return _demp;
}
set
{
_demp = value;
RaisePropertyChanged("demp");
}
}
private Employee _Names;
public Employee Names
{
get
{
return _Names;
}
set
{
_Names = value;
List<Employee> myList = new List<Employee>();
IEnumerable<Employee> myEnumerable = myList;
// List<Employee> listAgain = myEnumerable.ToList();
// Employees = (ObservableCollection<Employee>)Employees.Where(_ => _.Dept.Equals(Names.Dept));
RaisePropertyChanged("Names");
}
}
public void HandleShowMessage()
{
// MessageBox.Show("Hello " + Names + ",Welcome to EventTrigger for MVVM.");
}
public RelayCommand _AddEmployeeCommand;
/// <summary>
/// Returns a command that show the customer.
/// </summary>
public ICommand AddEmployeeCommand
{
get
{
if (_AddEmployeeCommand == null)
{
_AddEmployeeCommand = new RelayCommand(
param => this.AddEmployee(),
param => this.CanAddEmployee
);
}
return _AddEmployeeCommand;
}
}
public bool CanAddEmployee
{
get
{
return true;
}
}
public void AddEmployee()
{
Employee newEmployee = new Employee();
if (Names == null)
{
newEmployee.Fname = this.Fname;
newEmployee.Sname = this.Sname;
newEmployee.Dept = this.Dept;
Employees.Add(newEmployee);
//SelectedEmployee = newEmployee.ToString();
}
else //This is the event for getting selected item through combobox and the linq query fetching
{
Employees = Silverlight_MVVM.DataHelper.EmployeeDataHelper.EmployeeData();
var semp = from emp in Employees where emp.Dept.Equals(Names.Dept) select emp;
}
}
#region INotifyPropertyChanged
// [field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}

How to solve postback in custom sever controls?

I am creating custom server controls.I created a textbox in this used this control in my page.But when page is posted back(postback) the value of textbox gets omitted..I thought of using viewstate here but m nt getting textbox value .May be m using in wrong way help me plz
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Reflection;
namespace DNWebComponent {
[DefaultProperty("Text")]
[ToolboxData("<{0}:DNTextBox runat=server></{0}:DNTextBox>")]
public class DNTextBox : WebControl, IDNComponent {
public String _ConnectedField;
private string _label;
private TextBox _txtBox;
private string _connectedField;
private string _MultiSeekField;
private string _InputTable;
public string ControlClientID;
public DNTextBox() {
_txtBox = new TextBox();
}
[PersistToViewState]
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text {
get {
String s = (String)ViewState["Text"];
return ((s == null) ? "[" + AspTextBox.Text + "]" : s);
}
set {
ViewState["Text"] = value;
}
}
public DNTextBox(string label)
: this() {
this._label = label;
}
public String Label {
get { return _label; }
set { _label = value; }
}
public String ConnectedField {
get { return _connectedField; }
set { _connectedField = value; }
}
public String MultiSeekField {
get { return _MultiSeekField; }
set { _MultiSeekField = value; }
}
public String InputTable {
get { return _InputTable; }
set { _InputTable = value; }
}
public TextBox AspTextBox {
get { return _txtBox; }
set { _txtBox = value; }
}
public string DivCss { get; set; }
protected override void RenderContents(HtmlTextWriter output) {
output.Write("<div class=\"" + DivCss + "\" >");
output.Write(Text);
output.Write(_label + ": ");
_txtBox.RenderControl(output);
output.Write("</div>");
}
public bool FillControl() {
return false;
}
protected override void LoadViewState(object savedState) {
base.LoadViewState(savedState);
PropertyInfo[] properties = GetType().GetProperties();
foreach (PropertyInfo property in properties) {
object[] attributes = property.GetCustomAttributes(typeof(PersistToViewState), true);
if (attributes.Length > 0) {
if (ViewState[property.Name] != null)
property.SetValue(this, ViewState[property.Name], null);
}
}
}
protected override object SaveViewState() {
ViewState["Text"] = AspTextBox.Text;
//PropertyInfo[] properties = GetType().GetProperties();
//foreach (PropertyInfo property in properties) {
// object[] attributes = property.GetCustomAttributes(typeof(PersistToViewState), true);
// if (attributes.Length > 0)
// ViewState[property.Name] = property.GetValue(this, null);
//}
return base.SaveViewState();
}
[AttributeUsage(AttributeTargets.Property)]
public class PersistToViewState : Attribute {
}
}
}
This is another way to achieve what you are trying to do that will handle all the events and viewstate information:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Reflection;
namespace DNWebComponent {
[DefaultProperty("Text")]
[ToolboxData("<{0}:DNTextBox runat=server></{0}:DNTextBox>")]
public class DNTextBox : WebControl, IDNComponent {
public String _ConnectedField;
private string _label;
private TextBox _txtBox;
private string _connectedField;
private string _MultiSeekField;
private string _InputTable;
public string ControlClientID;
public DNTextBox() {
_txtBox = new TextBox();
}
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text {
get {
String s = (String)ViewState["Text"];
return ((s == null) ? "[" + AspTextBox.Text + "]" : s);
}
set {
ViewState["Text"] = value;
}
}
public DNTextBox(string label)
: this() {
this._label = label;
}
public String Label {
get { return _label; }
set { _label = value; }
}
public String ConnectedField {
get { return _connectedField; }
set { _connectedField = value; }
}
public String MultiSeekField {
get { return _MultiSeekField; }
set { _MultiSeekField = value; }
}
public String InputTable {
get { return _InputTable; }
set { _InputTable = value; }
}
public TextBox AspTextBox {
get { return _txtBox; }
set { _txtBox = value; }
}
public string DivCss { get; set; }
protected override void OnInit(EventArgs e) {
var div = new Panel{ CssClass = DivCss };
div.Controls.Add(new Literal{ Text = Text });
div.Controls.Add(new Literal{ Text = _label + ":" });
div.Controls.Add(_txtBox);
Controls.Add(div);
}
public bool FillControl() {
return false;
}
}
}
This is happening because you have not added the child text box control to your control - because the text-box is not part of control tree, it will not retain its value (or other properties).
You should derive from CompositeControl (or develop UserControl) instead. For example,
...
public class DNTextBox : CompositeControl, IDNComponent {
private TextBox _txtBox;
protected override void CreateChildControls()
{
_txtBox = new TextBox();
_txtBox.ID = "T";
this.Controls.Add(_textBox);
}
public TextBox AspTextBox
{
get { EnsureChildControls(); return _txtBox; }
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write("<div class=\"" + DivCss + "\" >");
output.Write(Text);
output.Write(_label + ": ");
base.RenderContents(output); // this will create html for child controls
output.Write("</div>");
}
}
Disclaimer: illustrative code, not tested
Whenever, you need to refer to the text-box, make sure that you call EnsureChildControls as shown in AspTextBox property.
This code worked for me.I added a method add attribute
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace DNWebComponent {
[DefaultProperty("Text")]
[ToolboxData("<{0}:DNTextBox runat=server></{0}:DNTextBox>")]
public class DNTextBox : TextBox, IDNComponent {
public String _ConnectedField;
private string _label;
private TextBox _txtBox;
private string _connectedField;
private string _MultiSeekField;
private string _InputTable;
public string ControlClientID;
public DNTextBox() {
_txtBox = this;
}
public DNTextBox(string label)
: this() {
this._label = label;
}
public String Label {
get { return _label; }
set { _label = value; }
}
public String ConnectedField {
get { return _connectedField; }
set { _connectedField = value; }
}
public String MultiSeekField {
get { return _MultiSeekField; }
set { _MultiSeekField = value; }
}
public String InputTable {
get { return _InputTable; }
set { _InputTable = value; }
}
public TextBox AspTextBox {
get { return this; }
set { _txtBox = value; }
}
public string DivCss { get; set; }
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,
Name = "FullTrust")]
protected override void AddAttributesToRender(HtmlTextWriter writer) {
writer.AddAttribute("Label", Label);
writer.AddAttribute("Text", Text);
base.AddAttributesToRender(writer);
}
protected override void RenderContents(HtmlTextWriter output) {
output.Write("<div class=\"" + DivCss + "\" >");
output.Write(_label + ": ");
output.Write("</div>");
}
public bool FillControl() {
return false;
}
}
}

Create a hierarchy custom server control

I have a self-referencing table and I want to visualize it using:
<ol>
<li>
</li>
</ol>
I want to create a custom server data-bound control with templates, I have read the MSDN article:
http://msdn.microsoft.com/en-us/library/aa479322.aspx
But I think that, I have to use different aproach and inherit the
HierarchicalDataBoundControl
or implement
IHierarchicalDataSource
But I cannot find any examples, or something to read from.
Can someone point me to a book or an article, or explain it to me in steps how it needs to be done.
A summary of what is required is this:
A Control which extends HierarchicalDataSourceControl AND DataSourceControl that implements IHeirarchicalDataSource. Believe me working from the documentation provided took A LOT of trial and error but in the end it is worth it. Mines been on hold but shortly I'll complete a project using this which will be able to bind to any n depth structure + navigate it in code using Node.GetParent().GetChildren().Where .. etc. It's complicted and may be overkill for what you need and you may revert back to repeater. Given the posting length allowed at stackoverflow I can't give you full code listing (some 100k chars)
To give you a flavour of whats in my other code here is the generic IHierachicalDataSourceControl:
#region Generic Hierachical DatasourceControl
/// <summary>
/// Datasource control
/// </summary>
public class GenericHierachicalDataSourceControl<TDataContext, TNode, TEntity> : HierarchicalDataSourceControl, IHierarchicalDataSource
where TDataContext : DataContext, new()
where TNode : class,PNS.GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.IHeirachicalNode, new()
where TEntity : class,PNS.GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.IHeirachyNodeEntity, new()
{
NodeDataSourceView view;
protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
{
view = new NodeDataSourceView(viewPath);
return view;
}
public class NodeDataSourceView : HierarchicalDataSourceView
{
private string _viewPath;
public NodeDataSourceView(string viewPath)
{
_viewPath = viewPath;
}
public override IHierarchicalEnumerable Select()
{
var hierarchy = new HierarchicalEnumerable();
List<TNode> topNodes;
if (String.IsNullOrEmpty(_viewPath))
{
//get all top level nodes (ones without parents)
topNodes = GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.NodesDAL.GetTopLevelNodes().ToList();
}
else
{
//get the last node in the path
string[] nodes = _viewPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
topNodes = new List<TNode>();
topNodes.Add(GenericLinqNodeHeirachy<TDataContext, TNode, TEntity>.NodesDAL.GetNode(nodes[nodes.Length - 1]));
}
//for each node in the path
foreach (var node in topNodes)
{
if (node.Entity != null)
{
hierarchy.Add(node.Entity);
}
}
return hierarchy;
}
}
public class HierarchicalEnumerable : List<TEntity>, IHierarchicalEnumerable
{
public HierarchicalEnumerable()
: base()
{
}
public IHierarchyData GetHierarchyData(object enumeratedItem)
{
return enumeratedItem as IHierarchyData;
}
}
}
and another part:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web.UI.HtmlControls;
namespace BootstrapProject.CodeBase
{
public class GenericHierarchicalDataboundControl : HierarchicalDataBoundControl
{
private string _textField;
public string TextField
{
get { return _textField; }
set { _textField = value; }
}
protected override string TagName
{
get
{
return "div";
}
}
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
protected override void CreateChildControls()
{
if (null != Page && Page.IsPostBack && null != ViewState["_!DataBound"])
{
this.RequiresDataBinding = true;
this.EnsureDataBound();
}
}
protected override void PerformDataBinding()
{
IHierarchicalEnumerable dataSource = GetData(string.Empty).Select();
this.PerformDataBinding(0, this.Controls, dataSource);
this.MarkAsDataBound();
}
protected virtual void PerformDataBinding(int level, ControlCollection controls, IHierarchicalEnumerable dataSource)
{
if (null != dataSource)
{
//controls.Clear();
HtmlGenericControl ul = new HtmlGenericControl("ul");
foreach (object value in dataSource)
{
var itemData = dataSource.GetHierarchyData(value);
Control item = CreateAndBindControl(level, value);
ul.Controls.Add(item);
var data = dataSource.GetHierarchyData(value);
if (data != null && data.HasChildren)
{
IHierarchicalEnumerable childData = data.GetChildren();
PerformDataBinding(1 + level, item.Controls, childData);
}
controls.Add(ul);
}
}
}
protected virtual Control CreateAndBindControl(int level, object dataItem)
{
HtmlGenericControl li = new HtmlGenericControl("li");
string text = String.Empty;
if (!String.IsNullOrEmpty(TextField))
{
text = DataBinder.GetPropertyValue(dataItem, TextField).ToString();
}
else
{
text = dataItem.ToString();
}
li.Attributes.Add("rel", text);
li.Controls.Add(new HyperLink { Text = text });
return li;
}
}
}
And finally:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using BootstrapProject.CodeBase.DAL;
using PNS;
namespace BootstrapProject.CodeBase
{
public class NodeDataSourceControl : HierarchicalDataSourceControl, IHierarchicalDataSource
{
NodeDataSourceView view;
protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath)
{
view = new NodeDataSourceView(viewPath);
return view;
}
}
public class NodeDataSourceView : HierarchicalDataSourceView
{
private string _viewPath;
public NodeDataSourceView(string viewPath)
{
_viewPath = viewPath;
}
public override IHierarchicalEnumerable Select()
{
var hierarchy = new CMSPageHierarchicalEnumerable();
List<DAL.Node> topNodes;
if (String.IsNullOrEmpty(_viewPath))
{
//get all top level nodes (ones without parents)
topNodes = CMS.NodesDAL.GetTopLevelNodes().ToList();
}
else
{
//get the last node in the path
string[] nodes = _viewPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
topNodes = new List<DAL.Node>();
topNodes.AddRange(CMS.NodesDAL.GetNode(nodes[nodes.Length - 1]).NodeChildren);
}
//for each node in the path
foreach (var node in topNodes)
{
if (node.Page != null)
{
hierarchy.Add(node.Page);
}
}
return hierarchy;
}
}
}

Resources