Why in AsyncTaskManager PropertyChanged is always null? - c#

I Try to implement sth similar to the pattern presented in this article:
http://msdn.microsoft.com/en-us/magazine/dn605875.aspx
Below is my problem description:
In my View I have set:
<Button Content="LoadData" Command="{Binding LoadDataCommand}" />
<ListBox Grid.Row="1" x:Name="listBox" ItemsSource="{Binding DataSource.Result}"
Then in codeBehind:
this.DataContext = new ProductViewModel();
Then in ProductViewModel:
public AsyncTaskManager<ObservableCollection<Product>> DataSource { get; private set; }
AND:
public ProductViewModel()
{
_loadDataCommand = new DelegateCommand(LoadDataAction);
}
private void LoadDataAction(object p)
{
ProductRepository pRepository = new ProductRepository();
DataSource = new AsyncTaskManager<ObservableCollection<Product>>(pRepository.LoadProducts());
}
And In AsyncTaskManager PropertyChanged is always null :( Why is that? What is wrong with the binding ?
But when I delete "load data" button and _loadDataCommand and just simply set
ProductRepository pRepository = new ProductRepository();
DataSource = new AsyncTaskManager<ObservableCollection<Product>>(pRepository.LoadProducts());
in the ProductViewModel constructor then it work like in the example, but I want user to have possibility to invoke load data using button not on start in constructor :/
Below is the AsyncTaskManager code:
using System;
using System.ComponentModel;
using System.Threading.Tasks;
namespace PhoneClientApp.Models
{
public sealed class AsyncTaskManager<TResult> : INotifyPropertyChanged
{
public AsyncTaskManager(Task<TResult> task)
{
Task = task;
if (!task.IsCompleted)
{
var _ = WatchTaskAsync(task);
}
}
private async Task WatchTaskAsync(Task task)
{
try
{
await task;
}
catch
{
}
var propertyChanged = PropertyChanged;
if (propertyChanged == null)
return;
propertyChanged(this, new PropertyChangedEventArgs("Status"));
propertyChanged(this, new PropertyChangedEventArgs("IsCompleted"));
propertyChanged(this, new PropertyChangedEventArgs("IsNotCompleted"));
if (task.IsCanceled)
{
propertyChanged(this, new PropertyChangedEventArgs("IsCanceled"));
}
else if (task.IsFaulted)
{
propertyChanged(this, new PropertyChangedEventArgs("IsFaulted"));
propertyChanged(this, new PropertyChangedEventArgs("Exception"));
propertyChanged(this,
new PropertyChangedEventArgs("InnerException"));
propertyChanged(this, new PropertyChangedEventArgs("ErrorMessage"));
}
else
{
propertyChanged(this,
new PropertyChangedEventArgs("IsSuccessfullyCompleted"));
propertyChanged(this, new PropertyChangedEventArgs("Result"));
}
}
public Task<TResult> Task { get; private set; }
public TResult Result
{
get
{
return (Task.Status == TaskStatus.RanToCompletion)
? Task.Result
: default(TResult);
}
}
public TaskStatus Status
{
get { return Task.Status; }
}
public bool IsCompleted
{
get { return Task.IsCompleted; }
}
public bool IsNotCompleted
{
get { return !Task.IsCompleted; }
}
public bool IsSuccessfullyCompleted
{
get
{
return Task.Status ==
TaskStatus.RanToCompletion;
}
}
public bool IsCanceled
{
get { return Task.IsCanceled; }
}
public bool IsFaulted
{
get { return Task.IsFaulted; }
}
public AggregateException Exception
{
get { return Task.Exception; }
}
public Exception InnerException
{
get
{
return (Exception == null)
? null
: Exception.InnerException;
}
}
public string ErrorMessage
{
get
{
return (InnerException == null)
? null
: InnerException.Message;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}

Please try to create a minimal reproducible set of code, and observe your Output window in the debugger for data binding errors.
The following code works just fine for me (in LINQPad):
void Main()
{
var context = new ParserContext();
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
var xaml = #"<Grid><ListBox ItemsSource=""{Binding DataSource.Result}"" /></Grid>";
var element = (FrameworkElement)XamlReader.Parse(xaml, context);
element.DataContext = new ProductViewModel();
PanelManager.StackWpfElement(element);
}
class ProductViewModel
{
public ProductViewModel()
{
DataSource = new AsyncTaskManager<ObservableCollection<string>>(LoadProductsAsync());
}
private async Task<ObservableCollection<string>> LoadProductsAsync()
{
await Task.Delay(10000);
return new ObservableCollection<string> { "first", "second", "third" };
}
public AsyncTaskManager<ObservableCollection<string>> DataSource { get; private set; }
}
The list box is first shown empty, and then after a delay is populated with values.

Related

How to copy custom ObservableCollection elements to another custom ObservableCollection?

I created a MTObservableCollection class that derives from ObservableCollection for multithreading. This is how the function looks like:
public class MTObservableCollection<T> : ObservableCollection<T> where T: LogClassa
{
public MTObservableCollection() { }
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
if (CollectionChanged != null)
foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
{
DispatcherObject dispObj = nh.Target as DispatcherObject;
if (dispObj != null)
{
Dispatcher dispatcher = dispObj.Dispatcher;
if (dispatcher != null && !dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(
(Action)(() => nh.Invoke(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
DispatcherPriority.DataBind);
continue;
}
}
nh.Invoke(this, e);
}
}
}
And here is my LogClass
public class LogClass : INotifyPropertyChanged
{
private string timestamp;
private string title;
private string message;
private MTObservableCollection<LogClass> childRowLog = new MTObservableCollection<LogClass>();
public string TimeStamp
{
get { return timestamp; }
set
{
if( timestamp != value )
{
timestamp = value;
OnPropertyChanged("TimeStamp");
}
}
}
public string Title
{
get { return title; }
set
{
if( title!= value )
{
title= value;
OnPropertyChanged("Title");
}
}
}
public string Message
{
get { return message; }
set
{
if( message!= value )
{
message= value;
OnPropertyChanged("Message");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
So if I have two MTObservableCollection collections and I add elements to one of them such as:
public static MTObservableCollection<LogClass> parentLogCollection = new MTObservableCollection<LogClass>();
public MTObservableCollection<LogClass> childLogCollection = new MTObservableCollection<LogClass>();
childLogClass.Add( new LogClass { TimeStamp = "time", Title = "title", Message = "message" } );
Now if I want to add childLogCollection to parentLogCollection, I would do this:
parentLogCollection = new MTObservableCollection<LogClass>(childLogCollection);
I would think I need to create an implementation within the MBObservationCollection class which should be
public MTObservableCollection(MTObservableCollection<T> collection)
{
}
I just don't know what to input into it, how would I perform it?
Try changing the parent of your MTObservableCollection like this:
public MTObservableCollection(MTObservableCollection<T> collection) : base(collection)
{
}

Telerik RadComboBox WPF How to display list of values from database table?

I'm using MVVM with WPF and have a RadComboBox in my view that needs to be populated from my County table in my database. My viewmodel is as follows:
public class AddClientViewModel : BindableBase
{
private Client _client;
private Circuit _circuit;
private County _county;
private State _state;
private SubscriberSpecialty _subscriberSpecialty;
private IClientsRepository _repository = new ClientRepository();
private ICircuitRepository _circuitRepository = new CircuitRepository();
private ICountyRepository _countyRepository = new CountyRepository();
private IStateRepository _stateRepository = new StateRepository();
private ISubscriberSpecialty _subscriberSpecialtyRepository = new SubscriberSpecialtyRepository();
public AddClientViewModel()
{
SaveCommand = new RelayCommand(OnSave);
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public Client Client
{
get { return _client; }
set
{
if (value != _client)
{
_client = value;
PropertyChanged(this, new PropertyChangedEventArgs("Client"));
}
}
}
public Circuit Circuit
{
get { return _circuit; }
set
{
if(value != _circuit)
{
_circuit = value;
PropertyChanged(this, new PropertyChangedEventArgs("Circuit"));
}
}
}
public County County
{
get { return _county;}
set
{
if (value != _county)
{
_county = value;
PropertyChanged(this, new PropertyChangedEventArgs("County"));
}
}
}
public State State
{
get { return _state; }
set
{
if (value != _state)
{
_state = value;
PropertyChanged(this, new PropertyChangedEventArgs("State"));
}
}
}
public SubscriberSpecialty SubscriberSpecialty
{
get { return _subscriberSpecialty; }
set
{
if (value != _subscriberSpecialty)
{
_subscriberSpecialty = value;
PropertyChanged(this, new PropertyChangedEventArgs("SubscriberSpecialty"));
}
}
}
public Guid ClientId { get; set; }
public Guid CircuitId { get; set; }
public Guid CountyId { get; set; }
public Guid StateId { get; set; }
public Guid SubscriberSpecialtyId { get; set; }
public ICommand SaveCommand { get; set; }
public event Action<Client> AddClient = delegate { };
public async void LoadClient()
{
Client = await _repository.GetClientAsync(ClientId);
}
public async void LoadCircuit()
{
Circuit = await _circuitRepository.GetCircuitAsync(CircuitId);
}
public async void LoadCounty()
{
County = await _countyRepository.GetCountyAsync(CountyId);
}
public async void LoadState()
{
State = await _stateRepository.GetStateAsync(StateId);
}
public async void LoadSubscriberSpecialty()
{
SubscriberSpecialty = await _subscriberSpecialtyRepository.GetSubscriberSpecialtyAsync(SubscriberSpecialtyId);
}
private void OnAddClient()
{
AddClient(new Client {ClientId = Guid.NewGuid()});
}
private async void OnSave()
{
try
{
Client = await _repository.AddClientAsync(new Client());
}
catch (Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception", MessageBoxButton.OK,
MessageBoxImage.Warning);
}
}
}
The interface has the following:
Task<County> GetCountyAsync(Guid countyId);
The repository class calls the interface as:
public Task<List<County>> GetCountiesAsync()
{
return _context.Counties.ToListAsync();
}
My view then uses the following syntax:
<telerik:RadComboBox x:Name="Countycombo"
Grid.Column="1" Grid.Row="3"
ItemsSource="{Binding County.CountyName}"
DisplayMemberPath="CountyName" Width="120"/>
I defined a DataContext in the layout as follows:
<UserControl.DataContext>
<viewModels:AddClientViewModel />
</UserControl.DataContext>
When I run the application, the RadComboBox doesn't grab the values from the County table, into which I've loaded several values for CountyName. How do I correct the above code snippets to ensure my County Names are populated?
Update: When I remove County from County.CountyName, I receive the message stating Cannot resolve property CountyName in DataContext MySolution.ViewModels.MyViewModel What additional work is needed in the viewmodel either in LoadCounty or other sections?
I would suggest the following:
Introduce the ViewModel property that will hold a list of County objects:
private List<County> _counties;
public List<County> Counties
{
get { return _counties;}
set
{
if (value != _counties)
{
_counties = value;
PropertyChanged(this, new PropertyChangedEventArgs("Counties"));
}
}
}
Bind a ComboBox ItemsSource to the Counties property, and a ComboBox SelectedItem property to the County property.
<telerik:RadComboBox x:Name="Countycombo"
Grid.Column="1" Grid.Row="3"
ItemsSource="{Binding Counties}"
SelectedItem="{Binding County}"
DisplayMemberPath="CountyName" Width="120"/>
And you need to a place where you will load the counties with a repository call to a GetCountiesAsync. The result should be set to the ViewModel Counties property.
public async void LoadCounties()
{
Counties = await _countyRepository.GetCountiesAsync();
}
Not sure what is the best place to make that call.

On Property change took too much time and finally crash application

I am working on WPF MVVM Application.
I have a view (Employee) shown inside Main Region
this view (Employee) contain scoped regions within it where I show/display Employee details views. Its working fine till this place New, display update and delete
But I am facing strange problem with New Operation
If I create view for first time and click on new , Object got initialized my Data Object CurrentEmployee.
But If I load some previous data its been shown properly and then I click on New, my Data Object CurrentEmployee took too much time and finaly crash. the problem so far traced is in OnPropertyChange
Thanks any sort of help/suggestion is highly appriciated
whole code of view model
[Export(typeof(ITB_EMPLOYEEViewModel))]
public class TB_EMPLOYEEViewModel : ViewModelBase, ITB_EMPLOYEEViewModel
{
private TB_EMPLOYEE _currentTB_EMPLOYEE;
IRegionManager RefRegionManager;
IEventAggregator _eventAggregator;
[ImportingConstructor]
public TB_EMPLOYEEViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
: base(regionManager, eventAggregator)
{
RefRegionManager = regionManager;
HeaderInfo = "TB_EMPLOYEE";
_eventAggregator = eventAggregator;
OpenImageDialog = new DelegateCommand(OpenDialog, CanOpenDialog);
//CurrentTB_EMPLOYEE = new TB_EMPLOYEE();
//empHistoryVM = new TB_EMPLOYEE_HISTORYViewModel();
//UnLoadChild();
//LoadChild();
New();
}
private void LoadChild()
{
IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
if (regionManager.Regions.ContainsRegionWithName(RegionNames.EmployeeDetail))
{
IRegion region = regionManager.Regions[RegionNames.EmployeeDetail];
var empHistory = ServiceLocator.Current.GetInstance<uTB_EMPLOYEE_HISTORYView>();
if (region.GetView("EmployeeHistory") == null)// .Views.OfType<uTB_EMPLOYEE_HISTORYView>().SingleOrDefault() == null)
{
region.Add(empHistory, "EmployeeHistory");
}
if (CurrentTB_EMPLOYEE != null && CurrentTB_EMPLOYEE.ID!=0)
{
empHistoryVM = new TB_EMPLOYEE_HISTORYViewModel(CurrentTB_EMPLOYEE.ID);
}
else
{
empHistoryVM = new TB_EMPLOYEE_HISTORYViewModel();
}
empHistory.ViewModel = empHistoryVM;
region.Activate(region.GetView("EmployeeHistory"));
}
}
private void UnLoadChild()
{
IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
if (regionManager.Regions.ContainsRegionWithName(RegionNames.EmployeeDetail))
{
IRegion region = regionManager.Regions[RegionNames.EmployeeDetail];
if (region.GetView("EmployeeHistory") != null)// .Views.OfType<uTB_EMPLOYEE_HISTORYView>().SingleOrDefault() == null)
{
region.Remove(region.GetView("EmployeeHistory"));
}
}
}
#region DetailUserControls ViewModels
private TB_EMPLOYEE_HISTORYViewModel empHistoryVM;
#endregion DetailUserControls ViewModels
#region Commands
public DelegateCommand OpenImageDialog { get; set; }
private bool CanOpenDialog() { return true; }
public void OpenDialog()
{
using (OpenFileDialog objOpenFile = new OpenFileDialog())
{
if (objOpenFile.ShowDialog() == DialogResult.OK)
{
_currentTB_EMPLOYEE.PHOTO = Utility.ConvertImageToByte(objOpenFile.FileName);
CurrentEmployeeImage = Utility.ConvertByteToImage(_currentTB_EMPLOYEE.PHOTO);
}
}
}
public override void ShowSelectedRow()
{
if (RefRegionManager.Regions[RegionNames.MainRegion].Views.OfType<uTB_EMPLOYEEView>().SingleOrDefault() == null)
{
RefRegionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(uTB_EMPLOYEEView));
}
RefRegionManager.RequestNavigate(RegionNames.MainRegion, "uTB_EMPLOYEEView");
UnLoadChild();
LoadChild();
}
public override void RegisterCommands()
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault() != null)
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault().ToString() == "WPFApp.View.uTB_EMPLOYEEView")
{
GlobalCommands.ShowAllCommand.RegisterCommand(ShowAllCommand);
GlobalCommands.SaveCommand.RegisterCommand(SaveCommand);
GlobalCommands.NewCommand.RegisterCommand(NewCommand);
GlobalCommands.DeleteCommand.RegisterCommand(DeleteCommand);
GlobalCommands.CloseCommand.RegisterCommand(CloseCommand);
}
}
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault() != null)
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault().ToString() == "WPFApp.ListView.uListTB_EMPLOYEE")
{
GlobalCommands.CloseCommand.RegisterCommand(CloseCommand);
GlobalCommands.SearchCommand.RegisterCommand(SearchCommand);
GlobalCommands.PrintCommand.RegisterCommand(PrintCommand);
GlobalCommands.ExportToExcelCommand.RegisterCommand(ExportToExcelCommand);
GlobalCommands.ExportToWordCommand.RegisterCommand(ExportToWordCommand);
GlobalCommands.ExportToPDFCommand.RegisterCommand(ExportToPDFCommand);
}
}
}
public override bool CanShowAll()
{
return IsActive;
}
public override void ShowAll()
{
HeaderInfo = "TB_EMPLOYEE List";
if (RefRegionManager.Regions[RegionNames.MainRegion].Views.OfType<uListTB_EMPLOYEE>().SingleOrDefault() == null)
{
RefRegionManager.RegisterViewWithRegion(RegionNames.MainRegion, typeof(uListTB_EMPLOYEE));
}
RefRegionManager.RequestNavigate(RegionNames.MainRegion, "uListTB_EMPLOYEE");
UpdateListFromDB();
}
public override void UpdateListFromDB()
{
using (DBMain objDBMain = new DBMain())
{
TB_EMPLOYEEList = objDBMain.EntTB_EMPLOYEE.ToList<TB_EMPLOYEE>();
}
}
public override void New()
{
this.CurrentTB_EMPLOYEE = new TB_EMPLOYEE();
UnLoadChild();
LoadChild();
}
public override void Close()
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault() != null)
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault().ToString() == "WPFApp.View.uTB_EMPLOYEEView")
{
RefRegionManager.Regions[RegionNames.MainRegion].Remove(RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault());
UnLoadChild();
}
}
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault() != null)
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault().ToString() == "WPFApp.ListView.uListTB_EMPLOYEE")
{
RefRegionManager.Regions[RegionNames.MainRegion].Remove(RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault());
}
}
}
public override void Delete()
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault() != null ||
RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault() != null)
{
if (CurrentTB_EMPLOYEE != null)
{
ConfirmationDialog confirmationMessage = new ConfirmationDialog("Do You want to Delete this Record of [TB_EMPLOYEE]", "Confirmation Dialog Box");
confirmationMessage.AllowsTransparency = true;
DoubleAnimation animFadeIn = new DoubleAnimation();
animFadeIn.From = 0;
animFadeIn.To = 1;
animFadeIn.Duration = new Duration(TimeSpan.FromSeconds(1));
confirmationMessage.BeginAnimation(Window.OpacityProperty, animFadeIn);
confirmationMessage.ShowDialog();
if (confirmationMessage.DialogValue)
{
if (CurrentTB_EMPLOYEE.ID != 0)
{
using (DBMain objDBMain = new DBMain())
{
objDBMain.Entry<TB_EMPLOYEE>(CurrentTB_EMPLOYEE).State = EntityState.Deleted;
objDBMain.SaveChanges();
OnPropertyChanged("CurrentTB_EMPLOYEE");
CurrentTB_EMPLOYEE = null;
}
}
else
{
CurrentTB_EMPLOYEE = null;
}
UpdateListFromDB();
}
}
}
}
public override bool CanSave()
{
return IsActive;
}
public override void Save()
{
if (RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uTB_EMPLOYEEView>().FirstOrDefault() != null ||
RefRegionManager.Regions[RegionNames.MainRegion].ActiveViews.OfType<uListTB_EMPLOYEE>().FirstOrDefault() != null)
{
if (CurrentTB_EMPLOYEE != null)
{
using (DBMain objDBMain = new DBMain())
{
objDBMain.Entry<TB_EMPLOYEE>(CurrentTB_EMPLOYEE).State = CurrentTB_EMPLOYEE.ID == 0 ? EntityState.Added : EntityState.Modified;
foreach (TB_EMPLOYEE_HISTORY obj in empHistoryVM.TB_EMPLOYEE_HISTORYList)
{
objDBMain.Entry<TB_EMPLOYEE_HISTORY>(obj).State = EntityState.Added;
CurrentTB_EMPLOYEE.TB_EMPLOYEE_HISTORYList.Add(obj);
objDBMain.SaveChanges();
}
}
UpdateListFromDB();
}
}
}
#endregion Commands
#region Properties
private ImageSource _CurrentEmployeeImage;
public ImageSource CurrentEmployeeImage { get { return _CurrentEmployeeImage; } private set { _CurrentEmployeeImage = value; OnPropertyChanged("CurrentEmployeeImage"); } }//OnPropertyChanged("CurrentTB_EMPLOYEE");
public string CurrentEmployeeImagePath { get; set; }
private List<TB_EMPLOYEE> _TB_EMPLOYEEList;
public List<TB_EMPLOYEE> TB_EMPLOYEEList
{
get { return _TB_EMPLOYEEList; }
set
{
_TB_EMPLOYEEList = value;
RaisePropertyChanged();
}
}
public TB_EMPLOYEE CurrentTB_EMPLOYEE
{
get { return _currentTB_EMPLOYEE; }
set
{
_currentTB_EMPLOYEE = value;
if (_currentTB_EMPLOYEE != null && _currentTB_EMPLOYEE.PHOTO != null)
{ CurrentEmployeeImage = Utility.ConvertByteToImage(_currentTB_EMPLOYEE.PHOTO); }
//OnPropertyChanged("CurrentTB_EMPLOYEE");
RaisePropertyChanged();
}
}
private IList<TB_SETUP_RELIGION> _listRELIGION;
public IList<TB_SETUP_RELIGION> listRELIGION
{
get
{
using (DBMain objDBMain = new DBMain())
{
_listRELIGION = objDBMain.EntTB_SETUP_RELIGION.ToList();
}
return _listRELIGION;
}
}
private IList<string> _listTitles;
public IList<string> listTitles
{
get
{
if (_listTitles == null)
{
_listTitles = new List<string>();
_listTitles.Add("Mr");
_listTitles.Add("Miss");
_listTitles.Add("Mrs");
//_listTitles.Add("Mr");
}
return _listTitles;
}
}
private IList<TB_SETUP_GENDER> _listGENDER;
public IList<TB_SETUP_GENDER> listGENDER
{
get
{
using (DBMain objDBMain = new DBMain())
{
_listGENDER = objDBMain.EntTB_SETUP_GENDER.ToList();
}
return _listGENDER;
}
}
#endregion Properties
#region FormNavigation
private bool isActive;
public override bool IsActive
{
get
{
return this.isActive;
}
set
{
isActive = value;
OnIsActiveChanged();
}
}
protected virtual void OnIsActiveChanged()
{
if (IsActive)
{
_eventAggregator.GetEvent<SubscribeToEvents>().Publish(new Dictionary<string, string>() { { "View", "TB_EMPLOYEE" }, { "FileName", #"Subscribtion to Events" } });
}
else
{
_eventAggregator.GetEvent<UnSubscribeToEvents>().Publish(new Dictionary<string, string>() { { "View", "TB_EMPLOYEE" }, { "FileName", #"UnSubscribtion to Events" } });
}
UnRegisterCommands();
RegisterCommands();
}
public override bool IsNavigationTarget(NavigationContext navigationContext)
{
this.isActive = true;
return this.isActive;
}
public override void OnNavigatedFrom(NavigationContext navigationContext)
{
UnRegisterCommands();
this.isActive = false;
}
public override void OnNavigatedTo(NavigationContext navigationContext)
{
HeaderInfo = "TB_EMPLOYEE";
this.isActive = true;
RegisterCommands();
}
#endregion FormNavigation
}
Finally solve the problem. I was using single Object CurrentTB_EMPLOYEE as current data for my form and ActiveData Item of another List view. this view model handle both form and list views. I just remove CurrentTB_EMPLOYEE from ActiveData Item to my list view and bind them through another object.. when CurrentTB_EMPLOYEE become responsible only for form its start working properly. Thanks every one for your precious time.

WP7 - Refresh ListBox on navigation GoBack()

I have a MainPage.xaml where is ListBox and Button. When I click on the button then MainPage is navigated to AddPage.xaml. This page is for adding new items, there are two TextBoxes and submit Button. When I click on that submit Button,then data from TextBoxes are saved to XML file and then is called GoBack().
I need to refresh ListBox in my MainPage.xaml when Im going back from AddPage.xaml, but it doesnt work automaticly. How can I do that?
My MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<Context> Contexts { get; private set; }
public MainViewModel()
{
this.Contexts = new ObservableCollection<Context>();
}
public bool IsDataLoaded
{
get;
private set;
}
public void LoadData()
{
try
{
var file = IsolatedStorageFile.GetUserStoreForApplication();
XElement xElem;
using (IsolatedStorageFileStream read = file.OpenFile("contexts.xml", FileMode.Open))
{
xElem = XElement.Load(read);
}
var contexts = from context in xElem.Elements("Context")
orderby (string)context.Element("Name")
select context;
foreach (XElement xElemItem in contexts)
{
Contexts.Add(new Context
{
Name = xElemItem.Element("Name").Value.ToString(),
Note = xElemItem.Element("Note").Value.ToString(),
Created = xElemItem.Element("Created").Value.ToString()
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
this.IsDataLoaded = true;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
and Context.cs
public class Context : INotifyPropertyChanged
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
NotifyPropertyChanged("Name");
}
}
}
private string _note;
public string Note
{
get
{
return _note;
}
set
{
if (value != _note)
{
_note = value;
NotifyPropertyChanged("Note");
}
}
}
private string _created;
public string Created
{
get
{
return _created;
}
set
{
if (value != _created)
{
_created = value;
NotifyPropertyChanged("Created");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You'll need to tell the main page that there is new data to reload.
At it's simplest, something like this:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
(this.DataContext as MainViewModel).LoadData();
}
}
Tip: You aren't raising a property changed notification for your View Model's properties.
On the load event of the MainPage, call LoadData. You should also clear the observable collection when you call the LoadData method before adding anything to it because simply loading the data will cause duplicate entries in your collection.

Property set inside async callback not staying set

So I've got an odd bug I'm hoping someone can help me with.
I have the following code to grab some entities from WCF RIA Services, this is in Silverlight 4, though my guess is that doesn't make a difference.
What am I missing?
public class MyModel
{
...
public IEnumerable<MyEntity> Result { get; private set; }
public void Execute()
{
Context.Load(Query, LoadBehavior.RefreshCurrent, o =>
{
if (o.HasError)
{
ExecuteException = o.Error;
if (ExecuteError != null)
ExecuteError(this, EventArgs.Empty);
o.MarkErrorAsHandled();
}
else
{
//I've stepped through the code and the assignment is working
//Result != null
Result = o.Entities;
if (ExecuteSuccess != null)
ExecuteSuccess(this, EventArgs.Empty);
//Inside any Handler of ExecuteSuccess
//MyModel.Result == null
//However I set a break point after ExecuteSuccess is triggered,
//and once again MyModel.Result != null
}
if (ExecuteComplete != null)
ExecuteComplete(this, EventArgs.Empty);
ExecuteBusy = false;
}, false);
}
}
Everything works until I get to this point:
MyModel.ExecuteSuccess += (o,e) => {
//At this point MyModel.Result == null. but why?
var result = MyModel.Result;
};
Yeah I found the issue I was doing some crazy stuff in order to make MVVM + RIA Services more fun, in an inheriting class I was casting MyModel.Result to MyModel.Result as IEnumerable<TEntity>; which doesn't work. I used MyModel.Result.OfType<TEntity> instead. I'm posting all the code in case it's useful to someone else.
public abstract class RiaQuery : INotifyPropertyChanged
{
#region INotifyPropertyChanged values
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Query
private EntityQuery _Query;
public EntityQuery Query
{
get { return _Query; }
private set
{
if (_Query != value)
{
_Query = value;
RaisePropertyChanged("Query");
}
}
}
#endregion
#region Result
private IEnumerable _Result;
public IEnumerable Result
{
get { return _Result; }
private set
{
if (_Result != value)
{
_Result = value;
RaisePropertyChanged("Result");
}
}
}
#endregion
#region ExecuteBusy
private bool _ExecuteBusy;
public bool ExecuteBusy
{
get { return _ExecuteBusy; }
private set
{
if (_ExecuteBusy != value)
{
_ExecuteBusy = value;
RaisePropertyChanged("ExecuteBusy");
}
}
}
#endregion
#region ExecuteCommand
private DelegateCommand _ExecuteCommand;
public DelegateCommand ExecuteCommand
{
get
{
if (_ExecuteCommand == null)
{
_ExecuteCommand = new DelegateCommand(o => Execute(o), o => !ExecuteBusy);
}
return _ExecuteCommand;
}
}
#endregion
#region ExecuteException
private Exception _ExecuteException;
public Exception ExecuteException
{
get { return _ExecuteException; }
private set
{
if (_ExecuteException != value)
{
_ExecuteException = value;
RaisePropertyChanged("ExecuteException");
}
}
}
#endregion
public event EventHandler ExecuteBegin;
public event EventHandler ExecuteComplete;
public event EventHandler ExecuteSuccess;
public event EventHandler ExecuteError;
protected DomainContext Context;
public bool CreateQueryEachTime { get; set; }
public RiaQuery(DomainContext context)
{
if (context == null) throw new ArgumentException("context");
Context = context;
}
public void Execute(object param)
{
ExecuteBusy = true;
if (ExecuteBegin != null)
ExecuteBegin(this, EventArgs.Empty);
if (CreateQueryEachTime || Query == null)
CreateQueryInternal();
Context.Load(Query, LoadBehavior.RefreshCurrent, o =>
{
if (o.HasError)
{
ExecuteException = o.Error;
if (ExecuteError != null)
ExecuteError(this, EventArgs.Empty);
o.MarkErrorAsHandled();
}
else
{
Result = o.Entities;
if (ExecuteSuccess != null)
ExecuteSuccess(this, EventArgs.Empty);
}
if (ExecuteComplete != null)
ExecuteComplete(this, EventArgs.Empty);
ExecuteBusy = false;
}, false);
}
private void CreateQueryInternal()
{
Query = CreateQuery();
}
protected abstract EntityQuery CreateQuery();
}
public abstract class RiaQuery<TContext> : RiaQuery
where TContext : DomainContext
{
new protected TContext Context
{
get { return base.Context as TContext; }
set { base.Context = value; }
}
public RiaQuery(TContext context) : base(context) { }
}
public abstract class RiaQuery<TContext,TEntity> : RiaQuery<TContext>
where TContext : DomainContext
where TEntity : Entity
{
new public EntityQuery<TEntity> Query
{
get { return base.Query as EntityQuery<TEntity>; }
}
new public IEnumerable<TEntity> Result
{
get { return base.Result.OfType<TEntity>(); }
}
public RiaQuery(TContext context) : base(context) { }
}
public class DelegateRiaQuery<TContext> : RiaQuery<TContext>
where TContext : DomainContext
{
protected Func<TContext, EntityQuery> CreateQueryDelegate;
public DelegateRiaQuery(TContext context, Func<TContext, EntityQuery> createQueryDelegate)
: base(context)
{
if (createQueryDelegate == null) throw new ArgumentException("createQueryDelegate");
CreateQueryDelegate = createQueryDelegate;
}
protected override EntityQuery CreateQuery()
{
return CreateQueryDelegate(Context);
}
}
public class DelegateRiaQuery<TContext, TEntity> : RiaQuery<TContext, TEntity>
where TContext : DomainContext
where TEntity : Entity
{
protected Func<TContext, EntityQuery<TEntity>> CreateQueryDelegate;
public DelegateRiaQuery(TContext context, Func<TContext, EntityQuery<TEntity>> createQueryDelegate) : base(context)
{
if (createQueryDelegate == null) throw new ArgumentException("createQueryDelegate");
CreateQueryDelegate = createQueryDelegate;
}
protected override EntityQuery CreateQuery()
{
return CreateQueryDelegate(Context);
}
}
Usage looks like this:
public class MyModel : INotifyPropertyChanged
{
...
public DelegateRiaQuery<MyContxt,MyEntity> MyModelOperation { get; private set; }
public MyModel()
{
var context = new MyContext();
MyModelOperation = new DelegateRiaQuery(context, c => c.GetMyModelEntitiesQuery(this.Property1));
}
}

Categories