Update context from object function - c#

In my window, I need to set a list of FileWatcher, for a list on machines.
For this I set a new class MachineWatcher :
public class MachineWatcher : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
{
if (object.Equals(variable, valeur)) return false;
variable = valeur;
NotifyPropertyChanged(nomPropriete);
return true;
}
private Machine machine { get; set; }
public Machine Machine { get { return this.machine; } set { this.machine = value; } }
private string typeWatcher { get; set; } = "";
public string TypeWatcher { get { return this.typeWatcher; } set { this.typeWatcher = value; } }
FileSystemWatcher watcher { get; set; }
public FileSystemWatcher Watcher { get { return this.watcher; } set { this.watcher = value; } }
private string lastFileName { get; set; } = "";
private DateTime lastEvent { get; set; } = DateTime.MinValue;
private ObservableCollection<string> listErrors { get; set; } = new ObservableCollection<string>();
public ObservableCollection<string> ListErrors { get { return this.listErrors; } set { this.listErrors = value; NotifyPropertyChanged("ListErrors"); } }
public MachineWatcher()
{
}
public MachineWatcher(string type,string directoryStock,string fileFilter)
{
this.typeWatcher = type;
this.watcher = new FileSystemWatcher
{
Path = Path.GetDirectoryName(directoryStock),
Filter = fileFilter
};
if (this.typeWatcher=="stock")
{
this.watcher.Created += new FileSystemEventHandler(OnStockFileCreated);
}
else if(this.typeWatcher=="machine")
{
//this.watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.LastAccess | NotifyFilters.CreationTime;
this.watcher.Changed += OnFeedBackNesterCreated;
this.watcher.Created += OnFeedBackNesterCreated;
this.watcher.Renamed += OnFeedBackNesterCreated;
this.watcher.Deleted += OnFeedBackNesterCreated;
}
this.watcher.EnableRaisingEvents = true;
}
private void OnFeedBackNesterCreated(object source, FileSystemEventArgs e)
{
try
{
//try to read file
}
catch
{
string errorText = "Error reading file " + e.FullPath;
this.ListErrors.Add(errorText);
}
}
}
Then in my mainWindow I defined a List<MachineWatcher>
I create then like that :
MachineWatcher machineWatcher = new MachineWatcher("stock", directoryStock, "*.csv");
this.listMachineWatchers.Add(machineWatcher);
What I would like, is when my MachineWatcher meets an error, and go in catch, update a Observable<string> ListErrors, where are written all the errors for all machines.
Is there a way to call a function in MainWindows from the object MachineWatcher?

Is there a way to call a function in MainWindows from the object MachineWatcher?
Yes, assuming you have a reference to the MainWindow in MachineWatcher.
You could for example inject the MachineWatcher class with a reference to MainWindow when you instantiate it:
private readonly MainWindow mainWindow;
public MachineWatcher(string type,string directoryStock,string fileFilter, MainWindow mainWindow)
{
this.typeWatcher = type;
this.watcher ...
this.mainWindow = mainWindow;
}
MainWindow:
MachineWatcher machineWatcher = new MachineWatcher("stock", directoryStock, "*.csv", this);
Then you can call any member of mainWindow directly from the MachineWatcher class.

Related

Update Datagrid from another ViewModel

I have a simple app that stores different stock data, my add stock button opens a new window with a form and when I press save I add the stock to the database but the datagrid doesn't get updated
I access the static instance of my main Viewmodel from my EntryViewModel via:
Main View Model(StockViewModel)
public class StockViewModel:INotifyPropertyChanged
{
#region Fields
private IList<Stock> _stockList;
private StatsBuilder _statsBuilder = new StatsBuilder();
public Stock stock = new Stock();
public Stock10 stock10 = new Stock10();
public Stock20 stock20 = new Stock20();
private ICommand _searchCommand;
private static StockViewModel _instance = new StockViewModel();
public static StockViewModel Instance { get { return _instance; } }
public IList<Stock> Stocks
{
get { return _stockList; }
set { _stockList = value; OnPropertyChanged(nameof(Stocks)); }
}
#endregion
#region Constructor
public StockViewModel()
{
using (var stocks = new AppDbContext())
{
Stocks = stocks.LowFloatStocks.ToList();
}
}
#endregion
#region Day1's
private string _ticker;
public string Ticker
{
get { return _ticker; }
set
{
_ticker = value;
OnPropertyChanged("Ticker");
}
}
private DateTime _date = DateTime.Now;
public DateTime Date
{
get { return _date; }
set { _date = value; }
}
private decimal _preivousClose;
public decimal PreviousClose
{
get { return _preivousClose; }
set { _preivousClose = value; OnPropertyChanged("PreviousClose"); }
}
private decimal _pmOpeningPrice;
public decimal PM_OpeningPrice
{
get { return _pmOpeningPrice; }
set { _pmOpeningPrice = value; OnPropertyChanged("PM_OpeningPrice"); }
}
private decimal _openingPrice;
public decimal OpeningPrice
{
get { return _openingPrice; }
set { _openingPrice = value; OnPropertyChanged("OpeningPrice"); }
}
private decimal _high;
public decimal High
{
get { return _high ; }
set { _high = value; OnPropertyChanged("High"); }
}
private decimal _low;
public decimal Low
{
get { return _low; }
set { _low = value; OnPropertyChanged("Low"); }
}
private decimal _close;
public decimal Close
{
get { return _close; }
set { _close = value; OnPropertyChanged("Close"); }
}
private string _catalyst;
public string Catalyst
{
get { return _catalyst; }
set { _catalyst = value; OnPropertyChanged("Catalyst"); }
}
private decimal _float;
public decimal Float
{
get { return _float; }
set {_float = value; OnPropertyChanged("Float"); }
}
private string _dilution;
public string Dilution
{
get { return _dilution; }
set { _dilution = value; OnPropertyChanged("Dilution"); }
}
#endregion
#region Day2's
//public decimal Day2Open
//{
// //get { return stock.Day2Open; }
// set { stock.Day2Open = value; OnPropertyChanged("Day2Open"); }
//}
//public decimal Day2High
//{
// get { return stock.Day2High; }
// set { stock.Day2High = value; OnPropertyChanged("Day2High"); }
//}
//public decimal Day2Low
//{
// get { return stock.Day2Low; }
// set { stock.Day2Low = value; OnPropertyChanged("Day2Low"); }
//}
//public decimal Day2Close
//{
// get { return stock.Day2Close; }
// set { stock.Day2Close = value; OnPropertyChanged("Day2Close"); }
//}
#endregion
#region Stats
private Stock _selectedstock;
public Stock SelectedStock
{
private get
{
return _selectedstock;
}
set
{
_selectedstock = value;
OnPropertyChanged("SelectedStock");
GetStats(_selectedstock.Ticker);
}
}
public int Gaps10 { get { return stock10.Gaps10; } set { stock10.Gaps10 = value; OnPropertyChanged("Gaps10"); } }
public decimal AvgGap10 { get {return stock10.AvgGap10; } set { stock10.AvgGap10 = value; OnPropertyChanged("AvgGap10"); } }
public int CloseGreen10 { get { return stock10.CloseGreen10; } set { stock10.CloseGreen10 = value; OnPropertyChanged("CloseGreen10"); } }
public decimal CloseGreenPercent10 { get { return stock10.CloseGreenPercent10; } set { stock10.CloseGreenPercent10 = value; OnPropertyChanged("CloseGreenPercent10"); } }
public int CloseRed10 { get { return stock10.CloseRed10; } set { stock10.CloseRed10 = value; OnPropertyChanged("CloseRed10"); } }
public decimal CloseRedPercent10 { get { return stock10.CloseRedPercent10; } set { stock10.CloseRedPercent10 = value; OnPropertyChanged("CloseRedPercent10"); } }
public decimal AvgSpike10 { get; set; }
public decimal Downside10 { get; set; }
public int PMFade10 { get { return stock10.PMFade10; } set { stock10.PMFade10 = value; OnPropertyChanged("PMFade10"); } }
public decimal PMFadePercent10 { get { return stock10.PMFadePercent10; } set { stock10.PMFadePercent10 = value; OnPropertyChanged("PMFadePercent10"); } }
public int Gaps20 { get {return stock20.Gaps20 ; } set { stock20.Gaps20 = value; OnPropertyChanged("Gaps20"); } }
public decimal AvgGap20 { get { return stock20.AvgGap20; } set { stock20.AvgGap20 = value; OnPropertyChanged("AvgGap20"); } }
public int CloseGreen20 { get { return stock20.CloseGreen20; } set { stock20.CloseGreen20 = value; OnPropertyChanged("CloseGreen20"); } }
public decimal CloseGreenPercent20 { get { return stock20.CloseGreenPercent20; } set { stock20.CloseGreenPercent20 = value; OnPropertyChanged("CloseGreenPercent20"); } }
public int CloseRed20 { get { return stock20.CloseRed20; } set { stock20.CloseRed20 = value; OnPropertyChanged("CloseRed20"); } }
public decimal CloseRedPercent20 { get { return stock20.CloseRedPercent20; } set { stock20.CloseRedPercent20 = value; OnPropertyChanged("CloseRedPercent20"); } }
public decimal AvgSpike20 { get; set; }
public decimal Downside20 { get; set; }
public int PMFade20 { get { return stock20.PMFade20; } set { stock20.PMFade20 = value; OnPropertyChanged("PMFade20"); } }
public decimal PMFadePercent20 { get { return stock20.PMFadePercent20; } set { stock20.PMFadePercent20 = value; OnPropertyChanged("PMFadePercent20"); } }
#endregion
#region PropertyChange
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Commands
public ICommand SearchCommand => _searchCommand ?? (_searchCommand = new RelayCommand(param => this.SearchStock(param)));
#endregion
#region Actions
private void SearchStock(object _ticker)
{
try
{
var stock = Stocks.First(x => x.Ticker.Trim() == _ticker.ToString());
_selectedstock = (Stock)stock;
GetStats(_ticker.ToString());
}
catch (Exception)
{
MessageBox.Show("No matching Ticker");
}
}
private void GetStats(string ticker)
{
//Stocks with 10% gap ups
stock10 = _statsBuilder.GetStats10(ticker);
stock20 = _statsBuilder.GetStats20(ticker);
Gaps10 = stock10.Gaps10;
AvgGap10 = stock10.AvgGap10;
CloseGreen10 = stock10.CloseGreen10;
CloseGreenPercent10 = stock10.CloseGreenPercent10;
CloseRed10 = stock10.CloseRed10;
CloseRedPercent10 = stock10.CloseRedPercent10;
PMFade10 = stock10.PMFade10;
PMFadePercent10 = stock10.PMFadePercent10;
//Stock with 20% gap ups
Gaps20 = stock20.Gaps20;
AvgGap20 = stock20.AvgGap20;
CloseGreen20 = stock20.CloseGreen20;
CloseGreenPercent20 = stock20.CloseGreenPercent20;
CloseRed20 = stock20.CloseRed20;
CloseRedPercent20 = stock20.CloseRedPercent20;
PMFade20 = stock20.PMFade20;
PMFadePercent20 = stock20.PMFadePercent20;
}
#endregion
}
When I click the add stock button it fires the AddCommand which in turn fires the Addstock method, this adds the stock to the database and updates the list in the StockViewModel instance but it does not update the datagrid OnPropertyChanged for some reason
EntryViewModel:
public ICommand AddCommand => _addCommand ?? (_addCommand = new RelayCommand(param => this.AddStock()));
#endregion
#region PropertyChange
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Methods
private void AddStock()
{
using (var stocks = new AppDbContext())
{
stock.Id = 0;
stock.Ticker = _ticker;
stock.PreviousClose = _preivousClose;
stock.PM_OpeningPrice = _pmOpeningPrice;
stock.OpeningPrice = _openingPrice;
stock.High = _high;
stock.Low = _low;
stock.Close = _close;
stock.Catalyst = _catalyst;
stock.Float = _float;
stock.Dilution = _dilution;
stocks.LowFloatStocks.Add(stock);
stocks.SaveChanges();
StockViewModel.Instance.Stocks = stocks.LowFloatStocks.ToList();
Clear();
}
}
Data Grid Binding;
<DataGrid Name="StockGrid" Margin="5,5,5,5" Height="250" ItemsSource="{Binding Stocks}" IsReadOnly="True" AutoGeneratingColumn ="StockGrid_AutoGeneratingColumn" Grid.ColumnSpan="3" VerticalScrollBarVisibility="Auto" SelectedItem="{Binding SelectedStock, Mode=TwoWay}">
</DataGrid>
Data Context of StockView Model:
<Window.DataContext> <local1:StockViewModel/> </Window.DataContext>
Any suggestions?
The following sets the DataContext to an new instance of the StockViewModel which is not the same as the instance returned by the Instance property:
<Window.DataContext> <local1:StockViewModel/> </Window.DataContext>
The fact that you can do this means that StockViewModel is not really a singleton. You should add a private constuctor to it to make it a real singleton if this is what you want:
private StockViewModel() { }
You would then set the DataContext to the instance returned by the Instance property:
<Window.DataContext>
<x:Static Member="this:StockViewModel.Instance" />
</Window.DataContext>

Select object and edit on form

I have a class an some objects from class. Now I want to select one of this object and display on my form. At the same time I want to edit the selected one. I used INotifyPropertyChanged and able to display selected object. Bu I have some troubles.
1- When I use myDislayingObject = myObject1 It does not work. So I have to use
myDislayingObject.property1 = myObject1.property1
myDislayingObject.property2 = myObject1.property2
I want to copy my object with all properties with one equality including events etc.
2- I am displaying properties on textboxes. When I edit the textboxes I does not changes the source object.
namespace DisplayObjectsInForm
{
public partial class Form1 : Form
{
public Araba Araba1 = new Araba();
public Araba Araba2 = new Araba();
public Araba Araba3 = new Araba();
public Araba DisplayingAraba = new Araba();
public Form1()
{
InitializeComponent();
Araba1.sName = "Araba1";
Araba1.sColor = "Kirmizi";
Araba1.nModel = 1999;
Araba2.sName = "Araba2";
Araba2.sColor = "Mavi";
Araba2.nModel = 2005;
Araba3.sName = "Araba3";
Araba3.sColor = "Gri";
Araba3.nModel = 2018;
textBox1.DataBindings.Add("Text", DisplayingAraba, "sName");
textBox2.DataBindings.Add("Text", DisplayingAraba, "sColor");
textBox3.DataBindings.Add("Text", DisplayingAraba, "nModel");
}
public class Araba : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public string sNameInternal;
public string sName
{
get
{
return sNameInternal;
}
set
{
if (sNameInternal != value)
{
sNameInternal = value;
NotifyPropertyChanged("sName");
}
}
}
public string sColorInternal;
public string sColor
{
get
{
return sColorInternal;
}
set
{
if (sColorInternal != value)
{
sColorInternal = value;
NotifyPropertyChanged("sColor");
}
}
}
public int nModelInternal;
public int nModel
{
get
{
return nModelInternal;
}
set
{
if (nModelInternal != value)
{
nModelInternal = value;
NotifyPropertyChanged("nModel");
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch(comboBox1.SelectedIndex)
{
case 0:
{
DisplayingAraba.sName = Araba1.sName;
DisplayingAraba.sColor = Araba1.sColor;
DisplayingAraba.nModel = Araba1.nModel;
break;
}
case 1:
{
DisplayingAraba.sName = Araba2.sName;
DisplayingAraba.sColor = Araba2.sColor;
DisplayingAraba.nModel = Araba2.nModel;
break;
}
case 2:
{
//Not working
DisplayingAraba = Araba3;
break;
}
}
}
}
}
It won't work because you initially set DisplayAraba to a newAraba.Try the following
namespace DisplayObjectsInForm
{
public partial class Form1 : Form
{
public Araba Araba1 = new Araba();
public Araba Araba2 = new Araba();
public Araba Araba3 = new Araba();
public Araba DisplayingAraba;//Remove the initialization from here.
public Form1()
{
InitializeComponent();
DisplayingAraba = new Araba(); //Add this line here
Araba1.sName = "Araba1";
Araba1.sColor = "Kirmizi";
Araba1.nModel = 1999;
Araba2.sName = "Araba2";
Araba2.sColor = "Mavi";
Araba2.nModel = 2005;
Araba3.sName = "Araba3";
Araba3.sColor = "Gri";
Araba3.nModel = 2018;

mvvm selected listview items to list<string> in object

I have a MVVM program with a model:
public class Deelnemer
{
public int Id { get; set; }
public string Voornaam { get; set; }
public string Werkplek { get; set; }
public List<string> Aanwezig { get; set; }
public Deelnemer()
{
}
}
In my View I have a listBox in which I want to be able to select multiple values (days to put in the list aanwezig).
<ListBox Name="listDagdelen" SelectionMode="Multiple" ItemsSource="{Binding Dagdelen}" SelectedItem="{Binding SelectedDagdeel, Mode=TwoWay}">
The ViewModel looks as follows:
class DeelnemerViewModel : INotifyPropertyChanged
{
#region Private Variables
private readonly Deelnemer dlnObject;
private readonly ObservableCollection<Deelnemer> deelnemers;
private readonly DeelnemerManager deelnemerManager;
private readonly ICommand addDeelnemerCmd;
private readonly ICommand deleteDeelnemerCmd;
#endregion
public ObservableCollection<string> Dagdelen { get; private set; }
#region constructor
public DeelnemerViewModel()
{
Dagdelen = new ObservableCollection<string>() { "maandagochtend", "maandagmiddag", "dinsdagochtend", "dinsdagmiddag", "woensdagochtend", "woensdagmiddag", "donderdagochtend", "donderdagmiddag", "vrijdagochtend", "vrijdagmiddag" };
dlnObject = new Deelnemer();
deelnemerManager = new DeelnemerManager();
deelnemers = new ObservableCollection<Deelnemer>();
addDeelnemerCmd = new RelayCommand(Add, CanAdd);
deleteDeelnemerCmd = new RelayCommand(Delete, CanDelete);
}
#endregion
#region Properties
private string _selectedDagdeel = null;
public string SelectedDagdeel
{
get { return _selectedDagdeel; }
set
{
_selectedDagdeel = value;
dlnObject.Aanwezig.Add(value);
OnPropertyChanged("SelectedDagdeel");
}
}
public int Id
{
get { return dlnObject.Id; }
set
{
dlnObject.Id = value;
OnPropertyChanged("Id");
}
}
public string Voornaam
{
get { return dlnObject.Voornaam; }
set
{
dlnObject.Voornaam = value;
OnPropertyChanged("Voornaam");
}
}
public string Werkplek
{
get { return dlnObject.Werkplek; }
set
{
dlnObject.Werkplek = value;
OnPropertyChanged("Werkplek");
}
}
public List<string> Aanwezig
{
get { return dlnObject.Aanwezig; }
set
{
dlnObject.Aanwezig = value;
OnPropertyChanged("Aanwezig");
}
}
public ObservableCollection<Deelnemer> Deelnemers { get { return deelnemers; } }
public Deelnemer SelectedDeelnemer
{
set
{
Id = value.Id;
Voornaam = value.Voornaam;
Werkplek = value.Werkplek;
Aanwezig = value.Aanwezig;
}
}
#endregion
#region Commands
public ICommand AddDeelnemerCmd { get { return addDeelnemerCmd; } }
public ICommand DeleteDeelnemerCmd { get { return deleteDeelnemerCmd; } }
#endregion
public bool CanAdd(object obj)
{
//Enable the Button only if the mandatory fields are filled
if (Voornaam != string.Empty && Werkplek != string.Empty)
return true;
return false;
}
public void Add(object obj)
{
var deelnemer = new Deelnemer { Voornaam = Voornaam, Werkplek = Werkplek, Aanwezig = Aanwezig };
if (deelnemerManager.Add(deelnemer))
{
Deelnemers.Add(deelnemer);
//string txt = string.Join(String.Empty,Aanwezig);
//MessageBox.Show(txt);
//ResetDeelnemer();
}
else
MessageBox.Show("Vul correcte waardes in!");
}
#region DeleteCommand
private bool CanDelete(object obj)
{
//Enable the Button only if the patients exist
if (Deelnemers.Count > 0)
return true;
return false;
}
private void Delete(object obj)
{
//Delete patient will be successfull only if the patient with this ID exists.
if (!deelnemerManager.Remove(Id))
MessageBox.Show("Deelnemer met dit id bestaat niet!");
else
{
//Remove the patient from our collection as well.
deelnemers.RemoveAt(GetIndex(Id));
ResetDeelnemer();
MessageBox.Show("Deelnemer succesvol verwijderd !");
}
}
#endregion
#region Private Methods
private void ResetDeelnemer()
{
Id = 0;
Voornaam = string.Empty;
Werkplek = string.Empty;
Aanwezig.Clear();
}
private int GetIndex(int Id)
{
for (int i = 0; i < Deelnemers.Count; i++)
if (Deelnemers[i].Id == Id)
return i;
return -1;
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
I can't figure out how I should use the List with the listbox values. How do I add (multiple) listbox values to the object's List?
The current code throws a nullreferenceexception at
dlnObject.Aanwezig.Add(value);
You must initialize the Aanwezig property of the Deelnemer object before you can add any values to it, either in the contructor of DeelnemerViewModel:
dlnObject = new Deelnemer();
dlnObject.Aanwezig = new List<string();
...or in the constructor of the Deeelnemer class:
public Deelnemer()
{
Aanwezig = new List<string();
}

Bound Textbox Not Updating on Change in Codebehind

I copied this code from another project and can't figure out why it isn't working. My observable collections are working great binding and updating, but my textboxes aren't changing. I have a button click that lets the user pick a directory (DirectoryBrowse() method) and then assigns that value to the data context's property that is bound to the textbox. PropertyChanged is always null and I can't figure out why! The initial binding works just fine, just note when I change the value in the code-behind. I've been at this entirely too long, but any help would be appreciated!
DataContext class:
[Serializable]
public class Settings : ViewModels.ViewModelEntity
{
public static Settings defaultSettings { get; set; }
private string _ExportDir;
public string ExportDir
{
get { return this._ExportDir; }
set
{
if (this._ExportDir != value)
{
this._ExportDir = value;
this.NotifyPropertyChanged("ExportDir");
}
}
}
private string _LastRunTime;
public string LastRunTime
{
get { return this._LastRunTime; }
set
{
if (this._LastRunTime != value)
{
this._LastRunTime = value;
this.NotifyPropertyChanged("LastRunTime");
}
}
}
private string _TSCertPath;
public string TSCertPath
{
get { return this._TSCertPath; }
set
{
if (this._TSCertPath != value)
{
this._TSCertPath = value;
this.NotifyPropertyChanged("TSCertPath");
}
}
}
public ObservableCollection<Map> Brokers { get; set; }
public ObservableCollection<Account> Accounts { get; set; }
public List<Holiday> Holidays { get; set; }
public bool RefreshHolidays { get; set; }
public string ProxyServer { get; set; }
public string ProxyPort { get; set; }
public string ProxyUsername { get; set; }
public string ProxyPassword { get; set; }
public bool TSProd { get; set; }
public string TSTriad { get; set; }
public string TSPassword { get; set; }
public string TSCertPassword { get; set; }
public Settings()
{
this.Brokers = new ObservableCollection<Map>();
this.Accounts = new ObservableCollection<Account>();
}
}
Xaml:
<TextBlock TextWrapping="Wrap" Text="File Export Path*"/>
<TextBox TextWrapping="Wrap" Text="{Binding Path=ExportDir, Mode=TwoWay}" />
<Button x:Name="btnBrowseExportDir" Content="..." Click="btnBrowseExportDir_Click"/>
Code-behind:
public MainWindow()
{
InitializeComponent();
Settings.Initialize();
this.DataContext = Settings.defaultSettings;
string[] args = Environment.GetCommandLineArgs();
if (args.Contains("create"))
{
this.Close();
}
}
private string DirectoryBrowse()
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
if (result.ToString().ToUpper() == "OK")
{
if (!Directory.Exists(dialog.FileNames.First()))
{
this.lblStatus.Text = "Invalid directory selected";
return string.Empty;
}
else
{
return dialog.FileNames.First();
}
}
else
{
this.lblStatus.Text = "Invalid directory selected";
return string.Empty;
}
}
private void btnBrowseExportDir_Click(object sender, RoutedEventArgs e)
{
Settings.defaultSettings.ExportDir = DirectoryBrowse();
}
ViewModelEntity:
public class ViewModelEntity
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Settings.defaultSettings is never assigned a value. So the databinding have nothing to work with.
Thoug code for Settings.Initialize() is missing.
#Dave and #Icepickle showed me what I was missing, no implementaiton of INotifyPropertyChanged!

How to update UI when ObservableCollection updated?

I have simple app, where ObservableCollection is updating in code and when new item added the UI is updated too. To update UI i am using a Dispatcher which is passed as a property to ViewModel. My code is works, but i don't know right i am or not.
Here is the code:
MainWindow.xaml.cs
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainWindowViewModel model = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = model;
this.model.dispatcher = this.Dispatcher;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string url = urlToCheck.Text;
Task task = new Task(() =>
{
model.GetUrls(url);
});
task.ContinueWith((previousTask) =>
{
label.Content = "Все ссылки собраны.";
},
TaskScheduler.FromCurrentSynchronizationContext());
label.Content = "Идёт сбор ссылок...";
task.Start();
}
}
MainWindowViewModel.cs
class MainWindowViewModel
{
public ObservableCollection<Url> Urls { get; set; }
public bool NeedToGetResponseForChildUrls { get; set; }
public bool NeedToDeletePreviousResults { get; set; }
public Dispatcher dispatcher;
some code.....................
**and something like this i am updating ObservableCollection:**
if (NeedToDeletePreviousResults)
{
dispatcher.Invoke(() =>
{
Urls.Clear();
});
}
Url.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace CheckUrl
{
public class Url : INotifyPropertyChanged
{
private string _absoluteUrl;
public string AbsoluteUrl
{
get { return _absoluteUrl; }
set
{
if (_absoluteUrl != value)
{
_absoluteUrl = value;
OnPropertyChanged("AbsoluteUrl");
}
}
}
private int _responseStatusCode;
public int ResponseStatusCode
{
get { return _responseStatusCode; }
set
{
if (_responseStatusCode != value)
{
_responseStatusCode = value;
OnPropertyChanged("ResponseStatusCode");
}
}
}
private string _responseStatusDescription;
public string ResponseStatusDescription
{
get { return _responseStatusDescription; }
set
{
if (_responseStatusDescription != value)
{
_responseStatusDescription = value;
OnPropertyChanged("ResponseStatusDescription");
}
}
}
public enum Status { Working, Broken };
private Status _urlStatus;
public Status UrlStatus
{
get { return _urlStatus; }
set
{
if (_urlStatus != value)
{
_urlStatus = value;
OnPropertyChanged("UrlStatus");
}
}
}
private string _color;
public string Color
{
get { return _color; }
set
{
if (_color != value)
{
_color = value;
OnPropertyChanged("Color");
}
}
}
private ObservableCollection<ChildUrl> _childUrlsValue = new ObservableCollection<ChildUrl>();
public ObservableCollection<ChildUrl> ChildUrls
{
get
{
return _childUrlsValue;
}
set
{
_childUrlsValue = value;
}
}
/// <summary>
/// Конструктор класса Url.
/// </summary>
public Url(string absoluteUrl, int responseStatusCode, string responseStatusDescription, Status urlStatus, string color)
{
this.AbsoluteUrl = absoluteUrl;
this.ResponseStatusCode = responseStatusCode;
this.ResponseStatusDescription = responseStatusDescription;
this.UrlStatus = urlStatus;
this.Color = color;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
ObservableCollection can update your UI automaticaly by using binding. Use a list of ObservableCollection and add / remove items from is. Make the ObservableCollection as a public property.In the MainWindow constructor write:
This.DataContext=This;
Use binding to your listBox / any other control you need to show the items on. ObservableCollection allready implement IINotifyPropertyChanged in it. Once you change the items in your ObservableCollection your UI will change as well.

Categories

Resources