I'm using mvvm thoughout my app and data binding and property changes are working everywhere else in the application but for some reason, on my view using XZing Barcode Scanner, my view is not updating after I scan an item.
I'm used to working with XAML ViewModel and Codebehind but they way I set up the barcode scanner is only ViewModel and Codebehind/alone class. So maybe I'm missing something simple that I am just not used to doing.
I've posted some code below that is an example of just one of the properties not updating, the PartName for productsLable.Text. It is bound when the page first loads and the dummy PartName shows correctly but after scanning a new item, I update the ScannedPart in my ViewModel but the "get" is never called after I set and call OnPropertyChanged();
This is working well in other parts of my application but maybe I am missing something silly here, like I said I am more comfortable working with bindings in XAML. Do you see anything I might be doing wrong or missing?
Thanks in advance.
public class TimsCustomScanPage : ContentPage
{
ZXingScannerView zxing;
TimsCustomOverlay overlay;
RequestPartsViewModel viewModel;
public TimsCustomScanPage(RequestPartsViewModel viewModel) : base()
{
//Attaching ViewModel
this.viewModel = viewModel;
this.BindingContext = viewModel;
//Scanner found barcode
zxing.OnScanResult += (result) =>
{
// Stop analysis until we navigate away so we don't keep reading barcodes
zxing.IsAnalyzing = false;
//Setting new scanned part
viewModel.ScannedPart = viewModel.Parts.FirstOrDefault();
};
--Some more code--
var productsLabel = new Label()
{
//Text = "Find New Part",
TextColor = Color.Black,
WidthRequest = 150,
HorizontalOptions = LayoutOptions.Start,
VerticalTextAlignment = TextAlignment.Center,
Padding = new Thickness(0, 0, 0, 0),
};
//Binding text property
productsLabel.SetBinding(Label.TextProperty, "PartName");
productsLabel.BindingContext = viewModel.ScannedPart;
}
ViewModel
public class RequestPartsViewModel : BaseViewModel
{
public ObservableCollection<TimsCategory> Categories { get; set; }
public ObservableCollection<TimsCategory> FavoriteCategories { get; set; }
public ObservableCollection<TimsPart> Parts { get; set; }
public TimsCategory CurrentSelection { get; set; }
public Command LoadItemsCommand { get; set; }
TimsPart scannedPart;
string partName;
int totalRequestedParts;
public RequestPartsViewModel()
{
Title = "Request Parts";
Categories = new ObservableCollection<TimsCategory>(db.Table<TimsCategory>().ToList());
Parts = new ObservableCollection<TimsPart>(db.Table<TimsPart>().ToList());
TotalRequestedParts = 0;
ScannedPart = new TimsPart();
ScannedPart.PartName = "Scan New Part";
ScannedPart.AvailableQuantity = 0;
//Attach parts to categories
foreach (var item in Categories)
{
int newId = item.CategoryId;
var partsForCategories = Parts.Where(p => p.CategoryId == newId);
var partsForCategoriesCollection = new ObservableCollection<TimsPart>(partsForCategories);
item.Parts = partsForCategoriesCollection;
}
FavoriteCategories = new ObservableCollection<TimsCategory>(Categories.Take(6).ToList());
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
}
public TimsPart ScannedPart
{
get
{
return scannedPart;
}
set
{
if (scannedPart != value)
{
scannedPart = value;
OnPropertyChanged("PartName");
OnPropertyChanged("RequestedQuantity");
OnPropertyChanged("AvailableQuantity");
OnPropertyChanged("ScannedPart");
}
}
}
Base ViewModel
public class BaseViewModel : INotifyPropertyChanged
{
public SQLiteConnection db = TimsData.database;
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
I think the problem is that you are binding directly to a property, but then changing the base object, not just the property. Try this instead
productsLabel.SetBinding(Label.TextProperty, "ScannedPart.PartName");
// you already have a BindingContext set for your page that the Label will inherit
// productsLabel.BindingContext = viewModel.ScannedPart;
Related
I am trying without success to bind some properties in XAML to the properties of some instantiated objects of a custom class I created.
What I have so far is (simplified):
In MainWindow.xaml:
<TextBox
Text="{Binding TEXTBOX.Text}"
...
<TextBox/>
In MainWindow.xaml.cs:
public MainWindow()
{
var viewModel = new ViewModel();
DataContext = viewModel;
InitializeComponent();
}
In ViewModel.cs:
public ViewModel()
{
GuiObject TEXTBOX = new GuiObject();
TEXTBOX.Text = "starting text";
}
In my GuiObject.cs:
public class GuiObject : INotifyPropertyChanged
{
private string _text = String.Empty;
public string Text
{
get => _text;
set => SetProperty(ref _text, value);
}
public event PropertyChangedEventHandler PropertyChanged;
public bool SetProperty<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
}
Can anybody please point me out how could I solve this issue?
Thanks in advance!
public ViewModel()
{
GuiObject TEXTBOX = new GuiObject();
TEXTBOX.Text = "starting text";
}
TEXTBOX here is a local variable. It is not accessible outside method. And binding needs public properties to work:
public ViewModel()
{
TEXTBOX = new GuiObject { Text = "starting text" };
}
public GuiObject TEXTBOX { get; set; }
also: naming guideline for properties is PascalCase (public GuiObject TextBox { get; set; })
I have been trying to open a property grid on the selection of a tree node and then bind the values of the property grid to the selected tree node in C#. This way if I create a new tree node it has its own values in the property grid.
Can anyone give an example of how that can be done or probably suggest me on the code below,
public partial class WPFpropertygriddemo : Window
{
public WPFpropertygriddemo()
{
InitializeComponent();
_propertyGrid.Visibility = Visibility.Hidden;
}
private void myTreeView_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem tvi = e.OriginalSource as TreeViewItem;
Item itemsub = (Item)tvi.Header;
if (itemsub != null)
{
_propertyGrid.Visibility = Visibility.Visible;
// System.Windows.MessageBox.Show(itemsub.DisplayValue);
_propertyGrid.SelectedObject = itemsub;
}
}
}
public class Item : MyModelINotifyProperty
{
public string DisplayValue { get; set; }
private bool _isSelected = false;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
private string _sample;
public string Sample
{
get
{
return _sample;
}
set
{
_sample = value;
OnPropertyChanged("Sample");
}
}
}
public class MyViewModel : MyModelINotifyProperty
{
public ObservableCollection<Item> Items
{
get
{
return new ObservableCollection<Item>()
{
new Item() {DisplayValue = "Item1", IsSelected = false, Sample = "Sample: I am Item1"},
new Item() {DisplayValue = "Item2", IsSelected = true, Sample = "Sample: I am Item2"},
new Item() {DisplayValue = "Item3", IsSelected = false, Sample = "Sample: I am Item3"}
};
}
}
}
public abstract class MyModelINotifyProperty : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
What I don't understand is where is TreeViewItem defined and what is the code line
"TreeViewItem tvi = e.OriginalSource as TreeViewItem;
doing? I have an error at the TreeViewItem and Original source. Am I supposed to add a reference to use the e.original?
Thanks
Sree.
So I have a page that has a TabControl that uses multiple UserControls (each user control represents the contents of a TabItem).
I have a ComboBox in both user controls that share the same ItemsSource (OrganizationSource) and SelectedValue(OrganizationSelected) properties,
I however cannot seem to bind to ComboBox within the EventDetails UserControl, but it works flawlessly inside of the OrganizationDetails UserControl.
The OutreachMVVM is set to the DataContext for the parent page that the tabs reside in. I still have to set the datacontexts for the user controls themselves for it to work properly.
I just need to figure out how to set the binding for the ComboBox inside of the EventDetails. I saw something about dependency property but I do not understand it. I thought I would be able to set the binding for the ComboBox inside of EventDetails as the same for the ComboBox inside of OrganizationDetails, but that's not the case.
internal class OutreachMVVM : ViewModelBase
{
public OutreachMVVM()
{
EventDetails = new EventDetailsVMB();
OrganizationDetails = new OrganizationDetailsVMB();
}
public EventDetailsVMB EventDetails { get; set; }
public OrganizationDetailsVMB OrganizationDetails { get; set; }
}
EventDetailsVMB:
class EventDetailsVMB : ViewModelBase
{
private string _eventTypeSelected;
private string _zipSelected;
private readonly UserListTableAdapter _userListTableAdapter = new UserListTableAdapter();
private readonly EventTypeListTableAdapter _eventTypeListTableAdapter = new EventTypeListTableAdapter();
private readonly CityListTableAdapter _cityListTableAdapter = new CityListTableAdapter();
private readonly LocationInfoByZipTableAdapter _locationInfoByZipTableAdapter = new LocationInfoByZipTableAdapter();
public string User { get; set; }
public string EventName { get; set; }
public string Location { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string County { get; set; }
public string ServiceArea { get; set; }
//Set EventType CombBox
public ObservableCollection<string> EventTypeSource
{
get
{
var eventTypeList = _eventTypeListTableAdapter.GetEventTypeList();
var eventTypeSource = new ObservableCollection<string>();
eventTypeSource.AddRange(from DataRow row in eventTypeList.Rows select row.ItemArray[0].ToString());
return eventTypeSource;
}
}
//Set User ComboBox
public ObservableCollection<string> UserSource
{
get
{
var userList = _userListTableAdapter.GetUserList();
var userSource = new ObservableCollection<string>();
foreach (var username in Enumerable.Where(userList, username => username.Username == Environment.UserName))
{
User = username.FullName;
}
userSource.AddRange(from DataRow row in userList.Rows select row.ItemArray[0].ToString());
OnPropertyChanged("User");
return userSource;
}
}
//Set City RadAutoCompleteBox
public ObservableCollection<string> CitySource
{
get
{
var cityList = _cityListTableAdapter.GetCityList();
var citySource = new ObservableCollection<string>();
citySource.AddRange(from DataRow row in cityList.Rows select row.ItemArray[0].ToString());
return citySource;
}
}
public string EventTypeSelected
{
get { return _eventTypeSelected; }
set
{
_eventTypeSelected = value;
OnPropertyChanged("EventTypeSelected");
}
}
public string ZipSelected
{
get { return _zipSelected; }
set
{
_zipSelected = value;
var locationInfo = _locationInfoByZipTableAdapter.GetLocationInfoByZip(_zipSelected);
if (locationInfo.Rows.Count != 0)
{
City = locationInfo.Rows[0].ItemArray[0].ToString();
State = locationInfo.Rows[0].ItemArray[1].ToString();
County = locationInfo.Rows[0].ItemArray[2].ToString();
ServiceArea = locationInfo.Rows[0].ItemArray[3].ToString();
}
else if (ZipSelected.Length == 5) {}
else
{
City = "";
State = "TX";
County = null;
ServiceArea = null;
}
OnPropertyChanged("City");
OnPropertyChanged("State");
OnPropertyChanged("County");
OnPropertyChanged("ServiceArea");
}
}
}
OrganizationDetailsVMB:
class OrganizationDetailsVMB : ViewModelBase
{
private string _organizationName;
private string _street1;
private string _street2;
private string _city;
private string _state;
private string _zip;
private string _county;
private string _serviceArea;
private bool _cbo;
private bool _fbo;
private bool _mo;
private bool _sbo;
private bool _sno;
private readonly OrganizationListTableAdapter _organizationListTableAdapter = new OrganizationListTableAdapter();
private readonly OrgByNameTableAdapter _orgByNameTableAdapter = new OrgByNameTableAdapter();
private readonly OrgTypeByOrgNameTableAdapter _orgTypeByOrgNameTableAdapter = new OrgTypeByOrgNameTableAdapter();
public string OrganizationSelected
{
get { return _organizationName; }
set
{
_organizationName = value;
var organizationQueryResults = _orgByNameTableAdapter.GetOrganizationByName(_organizationName);
var orgTypeQueryResults = _orgTypeByOrgNameTableAdapter.GetOrgTypeByName(_organizationName);
if (organizationQueryResults.Rows.Count != 0)
{
OrgStreet1Value = organizationQueryResults.Rows[0].ItemArray[1].ToString();
OrgStreet2Value = organizationQueryResults.Rows[0].ItemArray[2].ToString();
OrgCityValue = organizationQueryResults.Rows[0].ItemArray[3].ToString();
OrgStateValue = organizationQueryResults.Rows[0].ItemArray[4].ToString();
OrgZipValue = organizationQueryResults.Rows[0].ItemArray[5].ToString();
OrgCountyValue = organizationQueryResults.Rows[0].ItemArray[6].ToString();
OrgServiceAreaValue = organizationQueryResults.Rows[0].ItemArray[7].ToString();
CBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[1]);
FBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[2]);
SBO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[3]);
MO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[4]);
SNO = Convert.ToBoolean(orgTypeQueryResults.Rows[0].ItemArray[5]);
}
else
{
OrgStreet1Value = "";
OrgStreet2Value = "";
OrgCityValue = "";
OrgStateValue = "";
OrgZipValue = "";
OrgCountyValue = "";
OrgServiceAreaValue = "";
CBO = false;
FBO = false;
SBO = false;
MO = false;
SNO = false;
}
}
}
public ObservableCollection<string> OrganizationSource
{
get
{
var organizationList = _organizationListTableAdapter.GetOrganizationList();
var organizationSource = new ObservableCollection<string>();
organizationSource.AddRange(from DataRow row in organizationList.Rows select row.ItemArray[0].ToString());
return organizationSource;
}
}
public string OrgStreet1Value
{
get { return _street1; }
set
{
if (_street1 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStreet1Value" });
_street1 = value;
OnPropertyChanged("OrgStreet1Value");
}
}
}
public string OrgStreet2Value
{
get { return _street2; }
set
{
if (_street2 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStreet2Value" });
_street2 = value;
OnPropertyChanged("OrgStreet2Value");
}
}
}
public string OrgCityValue
{
get { return _city; }
set
{
if (_street1 != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgCityValue" });
_city = value;
OnPropertyChanged("OrgCityValue");
}
}
}
public string OrgStateValue
{
get { return _state; }
set
{
if (_state != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgStateValue" });
_state = value;
OnPropertyChanged("OrgStateValue");
}
}
}
public string OrgZipValue
{
get { return _zip; }
set
{
if (_zip != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgZipValue" });
_zip = value;
OnPropertyChanged("OrgZipValue");
}
}
}
public string OrgCountyValue
{
get { return _county; }
set
{
if (_county != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgCountyValue" });
_county = value;
OnPropertyChanged("OrgCountyValue");
}
}
}
public string OrgServiceAreaValue
{
get { return _serviceArea; }
set
{
if (_serviceArea != value)
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "OrgServiceAreaValue" });
_serviceArea = value;
OnPropertyChanged("OrgServiceAreaValue");
}
}
}
public bool CBO
{
get { return _cbo; }
set
{
_cbo = value;
OnPropertyChanged("CBO");
}
}
public bool FBO
{
get { return _fbo; }
set
{
_fbo = value;
OnPropertyChanged("FBO");
}
}
public bool SBO
{
get { return _sbo; }
set
{
_sbo = value;
OnPropertyChanged("SBO");
}
}
public bool MO
{
get { return _mo; }
set
{
_mo = value;
OnPropertyChanged("MO");
}
}
public bool SNO
{
get { return _sno; }
set
{
_sno = value;
OnPropertyChanged("SNO");
}
}
}
EventDetailsTab:
<TabItem Header="Event Details" x:Name="EventDetailsTab"
Style="{StaticResource TabStyle}"
DataContext="{Binding EventDetails}">
<eventTabs:_1_EventDetailsTab />
</TabItem>
OrganizationDetailsTab:
<TabItem Header="Organization" x:Name="OrganizationTab"
Style="{StaticResource TabStyle}"
DataContext="{Binding OrganizationDetails}">
<eventTabs:_2_OrganizationTab />
</TabItem>
As I said the bindings work flawlessly overall, but I want to reference a binding associated with OrganizationDetails for a control that resides in both the EventDetailsTab and OrganizationDetailsTab.
The code for that item is as follows...
<ComboBox Name="OrgNameComboBox" ItemsSource="{Binding OrganizationSource}"
SelectedValue="{Binding OrganizationSelected,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
You're setting the DataContext for your event details tab to {Binding EventDetails} and the DataContext for your organization tab to {Binding OrganizationDetails}, but the OrganizationSource and OrganizationSelected fields that your ComboBoxes are binding to only exist in the OrganizationDetailsVMB class. A quick hack would be to change your event details ComboBox to point to the correct place with a RelativeSource binding back to the TabItem's DataContext and down again to the OrganizationDetails:
<ComboBox Name="OrgNameComboBox" ItemsSource="{Binding OrganizationSource}"
DataContext="{Binding RelativeSource={RelativeSource AncestorType=TabControl}, Path=DataContext.OrganizationDetails}"
SelectedValue="{Binding OrganizationSelected,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
To be perfectly honest though I think you need to clean up your architecture. Your view model appears very tightly coupled to your underlying data model instead of the view, to the point where you're even accessing your table adapters in your getters which means A) you have no way of doing session management, B) your view performance will now be throttled by your DAL and you'll start having performance issues, and C) trying to introduce any type of multi-threading will cause all manner of access conflicts in your ORM.
A)
This way is good when you want have some data (like a combobox info) across an App or Multi Window:
Create 3 ViewModel (all inherited from INotifyPropertyChanged).
OrganizationViewModel: INCLUDE OrganizationSource and OrganizationSelected
OrganizationDetailsViewModel: WHITHOUT OrganizationSource and OrganizationSelected
OrganizationEventsViewModel: WHITHOUT OrganizationSource and OrganizationSelected
Now you can create a simple Static class named GeneralData & make a static property in it of OrganizationViewModel type like this:
public static class GeneralData{
public static OrganizationViewModel Organization {get;set;}
}
In the App.xaml.cs fill the Organization property of the GeneralData class with a new instance of OrganizationViewModel.
Ok... Now we have every things we need to start playing....
Every time you want to fill the ComboBox you should use the Organization [static property] of GeneralData class like this:
<ComboBox Name="OrgNameComboBox"
DataSource="{Binding Source={x:Static GeneralData.Organization}}"
ItemsSource="{Binding Source={x:Static GeneralData.Organization.OrganizationSource}}"
SelectedValue="{Binding Source={x:Static GeneralData.Organization.OrganizationSelected,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
And every time you want check which item of the Combobox is selected in code-behind (such as inside the ViewModels) you can easily check it like this:
var selectedOrganisation = GeneralData.Organization.OrganizationSelected;
Note: i recommend to you before closing the window that include the ComboBox run this code (to make sure there is not any alive reference to the static property):
BindingOperations.ClearAllBindings(OrgNameComboBox);
B)
If you have just 1 window include 2 UserControl then prevent static properties and instead of above way use this way:
Create 3 ViewModel (all inherited from INotifyPropertyChanged).
OrganizationViewModel: INCLUDE OrganizationSource and OrganizationSelected
OrganizationDetailsViewModel: WHITHOUT OrganizationSource and OrganizationSelected
OrganizationEventsViewModel: WHITHOUT OrganizationSource and OrganizationSelected
Now easily implement this scenario:
In Window1.xaml.cs:
Window1.DataSource= new OrganizationViewModel();
In EventUserControl.xaml.cs:
EventUserControl.DataSource= new OrganizationEventsViewModel();
In OrganizationDetailsUserControl.xaml.cs:
EventUserControl.DataSource= new OrganizationDetailsViewModel();
Now create a DependencyProperty in both EventUserControl and OrganizationDetailsUserControl to give them the SelectedItem of ComboBox. Your property type should be string. you can create the DependencyPropertys base on this tutorial.
For example use this name for your DependencyPropertys in both UserControls: SelectedOrganisation
OK, put the Combobox in the Window1.xaml (NOT inside any UserControl).
Now we fill these SelectedOrganisations from outer their UserControls like the following codes.
In Window1.xaml
<uc.OrganizationDetailsUserControl
SelectedOrganisation="{Binding ElementName=OrgNameComboBox, Path=SelectedItem}"/>
<uc.EventUserControl
SelectedOrganisation="{Binding ElementName=OrgNameComboBox, Path=SelectedItem}"/>
Now you have the SelectedItem of the ComboBox inside your UserControl you can play with it inside the UserControls and call some methods of the ViewModels with SelectedOrganisation as method parameter.
The route I took is the MVVM Light Toolkit.
I'm developing a program which involves graphical chart generation according to user inputs. Data for those graphs should be retrieved from the data base according to the inputs given by the user. I'm using modern UI charts library to generate charts. You can find the library here http://modernuicharts.codeplex.com/
Here is my mainWindow.xaml's screen shot :
http://imgur.com/eQUBl9w
Here user selects the graph type and pattern that he wants and the desired graph should be generated accordingly with the data available in the database. Currently I have followed the modern ui charts tutorial on above link and able to generate chart for only one LINQ query which is not based on user inputs. How can I get user inputs at runtime and execute different queries based on them and bind data at run time.
here is my mainWindo.xaml.cs
public partial class MainWindow : UserControl
{
public MainWindow()
{
InitializeComponent();
DataContext = new ChartController();
}
}
ChartController.CS
public class ChartController : INotifyPropertyChanged
{
public ObservableCollection<string> ChartTypes { get; set; }
public ChartController()
{
ChartTypes = new ObservableCollection<string>();
ChartTypes.Add("Pie");
ChartTypes.Add("Doughnut");
ChartTypes.Add("Clustered Bar");
ChartTypes.Add("Clustered Column");
ChartTypes.Add("Stacked Bar");
ChartTypes.Add("Stacked Column");
ChartTypes.Add("Stacked Bar Percentage");
ChartTypes.Add("Stacked Column Percentage");
}
private string _simpleStringProperty;
public string SimpleStringProperty
{
get { return _simpleStringProperty; }
set
{
_simpleStringProperty = value;
if (value.Equals("Pie"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\PieChart.xaml", UriKind.Relative);
}
if (value.Equals("Doughnut"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\DoughnutChart.xaml", UriKind.Relative);
}
if (value.Equals("Clustered Column"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\ClusteredColumnChart.xaml", UriKind.Relative);
}
if (value.Equals("Clustered Bar"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\ClusteredBarChart.xaml", UriKind.Relative);
}
if (value.Equals("Stacked Bar"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\StackedBarChart.xaml", UriKind.Relative);
}
if (value.Equals("Stacked Column"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\StackedColumnChart.xaml", UriKind.Relative);
}
if (value.Equals("Stacked Bar Percentage"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\StackedBarChart100Percent.xaml", UriKind.Relative);
}
if (value.Equals("Stacked Column Percentage"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\StackedColumnChart100Percent.xaml", UriKind.Relative);
}
if (value.Equals("Radial Gauge"))
{
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\RadialGaugeChart.xaml", UriKind.Relative);
}
OnPropertyChanged("SimpleStringProperty");
}
}
private Uri _selectedPageChart;
public Uri SelectedPageChart
{
get { return _selectedPageChart; }
set
{
_selectedPageChart = value;
OnPropertyChanged("SelectedPageChart");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
PieChart.xaml
<Grid>
<metroChart:PieChart
Style="{StaticResource MinimalChartStyle}"
ChartTitle="Minimal Pie Chart"
SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}" >
<metroChart:PieChart.Series>
<metroChart:ChartSeries
SeriesTitle="Errors"
DisplayMember="Year"
ValueMember="Cost"
ItemsSource="{Binding Path=Errors}" />
</metroChart:PieChart.Series>
</metroChart:PieChart>
</Grid>
PieChart.xaml.cs
public Page1()
{
InitializeComponent();
DataContext = new ChartViewModel();
}
chartViewModel.cs
namespace ModernUIForWPFSample.WithoutBackButton.Graphs.ViewModels
{
public class ChartViewModel
{
public ObservableCollection<stockLotsCostByYear> Errors { get; private set; }
public ChartViewModel()
{
adoraDBContext _c = new adoraDBContext();
var result = from ps in _c.PurchasingShipments
group ps by ps.date.Value.Year into grp
select new
{
Year = grp.Key,
Cost = grp.Sum(x => x.NoOfPieces * x.PricePerPiece + x.Micelleneous + x.TransportCost + x.SupplierCommission)
};
Errors = new ObservableCollection<stockLotsCostByYear>();
foreach (var d in result)
Errors.Add(new stockLotsCostByYear() { Year = d.Year, Cost = d.Cost });
}
private object selectedItem = null;
public object SelectedItem
{
get
{
return selectedItem;
}
set
{
selectedItem = value;
}
}
public class TestClass
{
public string Category { get; set; }
public int Number { get; set; }
}
public class stockLotsCostByYear
{
public int Year { get; set; }
public decimal? Cost { get; set; }
}
}
}
Not tested but should be something like that :
SelectedPageChart = new Uri("..\\Graphs\\GraphTemplates\\StackedBarChart.xaml?parameter=test", UriKind.Relative)
and in StackedBarChart cs :
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string parameter = string.Empty;
if (NavigationContext.QueryString.TryGetValue("parameter", out parameter)) {
this.label.Text = parameter;
}
}
I'm have a TextBox which gets added to a Window alongside a Checkbox. I've managed to bind the TextBox to property Order of the CheckedListItem handler so when a change is made it binds correctly and updates.
My problem I'm having is that I cannot get it to initialise with starting values. My constructor is as follows
public partial class OwnerSettingWindow : Window
{
public ObservableCollection<CheckedListItem<Owner>> Owners { get; set; }
public class Owner
{
public String OwnerName { get; set; }
public String OwnerOrder { get; set; }
}
public OwnerSettingWindow()
{
InitializeComponent();
Owners = new ObservableCollection<CheckedListItem<Owner>>();
string testString = #"Item1,true,1:Item2,true,2:Item3,false,24"; ;
string[] splitOwners = testString.Split(':');
foreach (string item in splitOwners)
{
string[] spOwnerSetting = item.Split(',');
bool bchecked = bool.Parse(spOwnerSetting[1].ToString());
string norder = spOwnerSetting[2].ToString();
Owners.Add(new CheckedListItem<Owner>(new Owner() { OwnerName = spOwnerSetting[0].ToString(), OwnerOrder = norder },
isChecked: bchecked));
}
DataContext = this;
}
public class CheckedListItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isChecked;
private T item;
private string order;
public CheckedListItem()
{ }
public CheckedListItem(T item, bool isChecked = false)
{
this.item = item;
this.isChecked = isChecked;
}
public T Item
{
get { return item; }
set
{
item = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
}
}
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
}
}
public string Order
{
get { return order; }
set
{
order = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Order"));
}
}
}
}
The following line not working as intended
Owners.Add(new CheckedListItem<Owner>(new Owner() { OwnerName =
spOwnerSetting[0].ToString(), OwnerOrder = norder },
isChecked: bchecked));
OwnerOrder = norder is not showing when the Window is opened. My TextBox binding in XAML is simply <TextBox Text ="{Binding Order}"/>
I've also tried the following with no success
Owners.Add(new CheckedListItem<Owner>(new Owner() { OwnerName = spOwnerSetting[0].ToString() },
isChecked: bchecked, order: norder));
Any ideas?
Order Property in CheckedListItem is never initialized. you can add a new ctor
public CheckedListItem(T item, string nrorder, bool isChecked = false)
{
this.item = item;
this.isChecked = isChecked;
this.order = nrorder;
}
and change your adding method
Owners.Add(new CheckedListItem<Owner>(new Owner() { OwnerName = spOwnerSetting[0].ToString(), OwnerOrder = norder }, norder, isChecked: bchecked));
In my test app now is working.