binding a list of class to a data grid UWP - c#

I would like to display this object(Node) in a data grid (coordinate is a custom class that literally describes a coordinate) -
public class Node
{
[JsonRequired]
private bool finished;
[JsonRequired]
private readonly string type;
[JsonRequired]
private coordinate starting_point = null;
[JsonRequired]
private string ID = "";
[JsonRequired]
public coordinate Final_Dest = null;
[JsonRequired]
public List<coordinate> check_points = new List<coordinate>();
[JsonRequired]
private string Metadata = "";
[JsonRequired]
private readonly SimpleMarkerSymbol symbol;
[JsonRequired]
private int Vmax;
[JsonRequired]
public int Amax;
[JsonRequired]
private int slope_max;
[JsonRequired]
private int slope_min;
[JsonRequired]
private int terrein_rank_reject;
[JsonRequired]
private int affinity_to_stay_in_group;
[JsonRequired]
public int GroupID;
[JsonRequired]
public bool coomplitionflag = false;
this is what I tried to do -
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
selected_nodes = (comboclass)e.Parameter;
postioning_index = selected_nodes.Get_index();
Node[] array_of_nodes = selected_nodes.Get_node_array();
dataGrid.ItemsSource = Create_list(array_of_nodes);//this function creates a list of nodes
}
public static List<Node> Create_list(Node[] array_nodes)
{
var node_coll = new List<Node>();
for (int i = 0; i < array_nodes.Length; i++)
{
node_coll.Add(array_nodes[i]);
}
return node_coll;
}
and for some reason when I execute it only shows the field -type on the data grid

binding a list of class to a data grid UWP
If you want to bind the Node instance, you need implement the public field's set get method.
Please edit your class like the following.
public class Node
{
public string Title { get; set; }
public coordinate Final_Dest { get; set; }
.......
}
For more detail please refer Data binding in depth document.

Related

Xamarin Shell : Pass multiple arguments to another page

I have two pages in my Xamarin Forms Shell app.
One list page and another is the details page.
when I select the item in list page, the detail page will be shown. I was able to pass one parameter to the second page. I know how to pass the second value. But how should I receive the second value in the first property itself.
List Page:
async private void myLines_ItemTapped(object sender, ItemTappedEventArgs e)
{
var line = (Models.QLines)e.Item;
int pno = line.PageNo;
int lno = line.LineNo;
await Shell.Current.GoToAsync($"//mainTabs/pages?pageno={pno}&lineno={lno}");
}
Detail Page:
public int CurrentPage { get; set; }
public int CurrentLine { get; set; }
public bool IsFromSearchPage { get; set; }
public string PageNo
{
set
{
CurrentPage = Convert.ToInt32(Uri.UnescapeDataString(value));
IsFromSearchPage = true;
LoadPagesAsSingle();
}
}
public string LineNo
{
set
{
CurrentLine = Convert.ToInt32(Uri.UnescapeDataString(value));
}
}
public MyPages()
{
InitializeComponent();
conn = DependencyService.Get<ISQLiteMyConnection>().GetConnection();
IsFromSearchPage = false;
LoadPagesAsSingle();
}
As explained in https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation#pass-data you can use QueryProperty attribute to map between queryID and the target property:
[QueryProperty("Pageno", "pageno")]
[QueryProperty("Lineno", "lineno")]
public partial class DetailPage: ContentPage
{
private int _Pageno;
public int Pageno
{
get { return _Pageno; }
set { _Pageno = value; }
}
private int _Lineno;
public int Lineno
{
get { return _Lineno; }
set { _Lineno = value; }
}
As another solution you can pass parameters through static members of page. For example page may contain static ViewModel object, which will be initialized before page appears.
public class ViewModel : ViewModelBase
{
public string Text { get; set; }
public int Number { get; set; }
}
public class MyPage : Page
{
static ViewModel _viewModel = new ViewModel();
public MyPage()
{
BindingContext = _viewModel;
}
public static void InitPage(string text, int number)
{
_viewModel.Text = text;
_viewModel.Number = number;
}
}
}
Code inside caller
static async Task GotoPage()
{
MyPage.InitPage("Text", 123);
await Shell.Current.GoToAsync($"//mainTabs/pages");
}
you can use parameters in the detailPage
public DetailPage(string val1,string val2)
{
}
then call it in MyPage
Navigation.PushAsync(new DetailPage("parameter1","parameter2"));

Looping over the value inside property which is present inside the struct

I have created a struct which have some properties such as
public struct DeviceDetailModel
{
public static readonly DeviceDetailModel DT851P = new DeviceDetailModel("851P","v1","v2");
public static readonly DeviceDetailModel DT852P = new DeviceDetailModel("852P","v3","v4");
public static readonly DeviceDetailModel DT83P = new DeviceDetailModel("853P","v5","v6");
public static readonly DeviceDetailModel DT854P = new DeviceDetailModel("854P");
public string DeviceName { get; private set; }
public string Value1 { get; private set; }
public string Value2 { get; private set; }
private DeviceDetailModel(string deviceName,string value1,string value2)
{
DeviceName = deviceName;
Value1 = value1;
Value2 = value2;
}
}
now if i want to get a detail of single item its easy i just had to do DeviceDetailModel.DT854P
but the issue I would be getting a value on runtime using which I had to identify which struct property I had to return
eg = my runtime value is 853P
I want to loop over my struct to identify where in DeviceName matched to this value 853P and which should return DeviceDetailModel.DT83P
I was able to loop over the properties of the struct but wasn't able to get value
Editing: Based on my run time value, i need to iterate over DeviceName's value and if the value matches it should return associated property
Here's one fairly simple option:
public struct DeviceDetailModel
{
private static readonly Dictionary<string, DeviceDetailModel> models = new Dictionary<string, DeviceDetailModel>
{
{"851P", new DeviceDetailModel("851P")},
{"852P", new DeviceDetailModel("852P")},
{"853P", new DeviceDetailModel("853P")},
{"854P", new DeviceDetailModel("854P")},
};
public static DeviceDetailModel DT851P get => models["851P"];
public static DeviceDetailModel DT852P get => models["852P"];
public static DeviceDetailModel DT83P get => models["853P"];
public static DeviceDetailModel DT854P get => models["854P"];
private DeviceDetailModel(string deviceName)
{
DeviceName = deviceName;
}
public string DeviceName {get;private set;}
public DeviceDetailModel? FindByDeviceName(string deviceName)
{
return models.TryGetValue(deviceName, out var value) ? value : (DeviceDetailModel)null;
}
}
Note that the return value of FindByDeviceName is a Nullable<DeviceDetailModel> so in case you're looking for a string that's not found you wont get an exception, but null.

Nested Class <List> : how to access nested class in list?

Basically i have one class with subclass(or nested class, inner class whatever it gets called)
I have no idea why i cant access (or list doesnt include nested class i guess)
nested class.
public static List<Tag> Tags = new List<Tag>();
//cureently selected tag,also random percentage related data
public class Tag
{
public string name = null;
public int dupe = 0;
public int Tagindex = 0;
public int URLindex = 0;
public class Type
{
public bool isArtist = false;
public bool isGroup = false;
public bool isTag = false;
public bool isURL = false;
}
public class Score
{
// 0~10, sort them out!
public bool isRated = false; //make true if user modifies score
public int Story = 0;
public int Reality = 0;
public int Drawing = 0;
public int memetic = 0;
public string msg = null;
}
dataGridView1.Rows.Add(gVar.Tags[i].Tagindex,gVar.Tags[i].name/*valid*/, gVar.Tags[i].Type.isArtist/*invalid*/);
//also invalid
Tag t1 = new Tag();
t1.Type.isArtist = true;
gVar.Tags.Add(t1);
The nested class is just a declaration of the class, same as if that class was not nested.
You have to instantiate an object of that type in order to access one of its properties.
For example:
public class Tag
{
public string name = null;
public int dupe = 0;
public int Tagindex = 0;
public int URLindex = 0;
public Score Score { get; } = new Score() // declare a property of the nested type, and instantiate an object
public class Type
{
public bool isArtist = false;
public bool isGroup = false;
public bool isTag = false;
public bool isURL = false;
}
public class Score
{
// 0~10, sort them out!
public bool isRated = false; //make true if user modifies score
public int Story = 0;
public int Reality = 0;
public int Drawing = 0;
public int memetic = 0;
public string msg = null;
}
And the usage:
Tag t1 = new Tag();
t1.Score.Story = 3;
By the way, it's not recommended to use public fields, use properties instead (such as the Score property in the code above).

Sharing Object between Views & ViewModels in MVVM

I'm new to WPF + MVVM and have been having trouble getting around viewmodels.
I have a object called FSystem which contains a alot of lists which are populated from a XML.
public class FSystem : ObservableObject
{
public List<FUser> _userList;
public List<FZone> _zoneList;
public List<FSource> _sourceList;
public string _projectName { get; set; }
private string _projectVersion { get; set; }
private string _processorIp { get; set; }
private bool _isMultiLingualModeOn { get; set; }
private int _systemIncludeLighting { get; set; }
private int _systemIncludeWindowsTreatments { get; set; }
private int _systemIncludeSip { get; set; }
private int _systemIncludeCamaras { get; set; }
public FSystem()
{
UserList = new List<FUser>();
}
}
This is the XMLParser which is called when the user loads the XML to the application.
public static class XMLParsers
{
public static FSystem ParseByXDocument(string xmlPath)
{
var fSystem = new FSystem();
XDocument doc = XDocument.Load(xmlPath);
XElement fSystemElement = doc.Element("FSystem");
if (fSystemElement != null)
{
fSystem.ProjectName = fSystemElement.Element("ProjectName").Value;
fSystem.ProjectVersion = fSystemElement.Element("ProjectVersion").Value;
fSystem.ProcessorIp = fSystemElement.Element("ProcessorIP").Value;
fSystem.ProcessorFilePath = fSystemElement.Element("ProcessorFilePath").Value;
fSystem.SystemIncludeLighting = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
fSystem.SystemIncludeSip = Convert.ToInt16(fSystemElement.Element("SystemIncludeLighting").Value);
fSystem.SystemIncludeCamaras = Convert.ToInt16(fSystemElement.Element("SystemIncludeCameras").Value);
}
fSystem.UserList = (from user in doc.Descendants("FUser")
select new FUser()
{
Id = user.Element("Id").Value,
Name = user.Element("Name").Value,
Icon = user.Element("IconColour").Value,
Pin = user.Element("UserPin").Value,
IsPinEnabled = Convert.ToBoolean(Convert.ToInt16(user.Element("UserPinEnabled").Value)),
ListIndex = user.Element("ListIndex").Value
}).ToList();
return fSystem;
}
}
And this is the MainViewModel below is what contains the Commands which Load the XML and the property FSystem I wish to use in other view models.
public class MainViewModel : ViewModel
{
private Fystem fSystem;
public FSystem FSystem
{
get { return fSystem; }
private set
{
fSystem = value;
NotifyPropertyChanged("FSystem");
}
}
public MainViewModel()
{
InitiateState();
WireCommands();
}
private void InitiateState()
{
FSystem = new FSystem();
}
private void WireCommands()
{
XDocumentLoadCommand = new RelayCommand(XDocumentLoad) {IsEnabled = true};
ClearDataCommand = new RelayCommand(ClearData) {IsEnabled = true};
}
public RelayCommand XDocumentLoadCommand { get; private set; }
private void XDocumentLoad()
{
var openDlg = new OpenFileDialog
{
Title = "Open .FAS",
DefaultExt = ".fas",
Filter = "F System Files (*.fas)|*.fas",
Multiselect = false
};
bool? result = openDlg.ShowDialog() == DialogResult.OK;
if (result != true) return;
FSystem = XMLParsers.ParseByXDocument(openDlg.FileName);
}
The application basically lets the user change the different objects (FUser,FZone,FSource, ect). The idea I had was the user would load the XML then be able to edit the different list objects on different views.
What would the correct way be to go about this in MVVM?
I plan to (hopefully) get the User, Zone and Source views to display Datagrids which are populated with their respective data from the Model.
Create you specific view models, and use dependency injection to pass the relevant data into them (this list or that list).
This way, the view models don't need to know about other stuff, and you can easily mock it for testing and for dummy data to see on the designer.
Copy paste into Linqpad for the simplest example. Both mock viewmodels take a dependency (i in our case). You can just pass your lists:
void Main()
{
int someInt = 5;
int anotherInt = 7;
VM vm1 = new VM(someInt);
VM vm2 = new VM(anotherInt);
vm1.RevealI();
vm2.RevealI();
}
public class VM{
private int _i;
public VM(int i)
{
_i = i;
}
public void RevealI() { Console.WriteLine("value of i is: " + _i); }
}
Othen than that, here's more items:
MSDN
Code Project
stack overflow

WPF Binding ObservableCollection to ComboBox

I try to bind a list of Lens Objects and I would like to display the LensName property in my combobox.My lists in my code contain objects but comboboxes remain empty or the property doesn't display.I already tried all the ways known to bind my data without result.Thanks for helping
Xaml
<ComboBox x:Name="RightbestlensCombo" ItemsSource="{Binding Source=RightBestLensList}" DisplayMemberPath="LensName" SelectedValuePath="LensTypeId" />
<ComboBox x:Name="LeftbestlensCombo" ItemsSource="{Binding Source=LefttBestLensList}" DisplayMemberPath="LensName" SelectedValuePath="LensTypeId" ></ComboBox>
Code Behind
public ObservableCollection<OphtalboxIA.Lens> RightBestlensList = new ObservableCollection<OphtalboxIA.Lens>();
public ObservableCollection<OphtalboxIA.Lens> LeftBestlensList = new ObservableCollection<OphtalboxIA.Lens>();
if (OphtalboxIA.OphtalboxComputingModule.LeftBestLensList != null)
{
if (OphtalboxIA.OphtalboxComputingModule.LeftBestLensList.Count > 0)
{
LeftBestlensList=new ObservableCollection<OphtalboxIA.Lens>(OphtalboxIA.OphtalboxComputingModule.LeftBestLensList);
//LeftbestlensCombo.ItemsSource = LeftBestlensList;
}
}
if (OphtalboxIA.OphtalboxComputingModule.RightBestLensList != null)
{
if (OphtalboxIA.OphtalboxComputingModule.RightBestLensList.Count > 0)
{
RightBestlensList=new ObservableCollection<OphtalboxIA.Lens>(OphtalboxIA.OphtalboxComputingModule.RightBestLensList);
//RightbestlensCombo.ItemsSource = RightBestlensList;
}
}
My class Lens
[XmlInclude(typeof(Lens))]
public class Lens{
public String LensName;
public String LensType;
public String LensTypeTrial;
public float Diameter;
public float Radius;
public float Sphere;
public float Cylinder;
public int Axis;
public String Addition;
public String Description;
public int isRX;
public int isOphtalBox;
public int priorityOrder;
public int LensFrequencyId;
public string LensFrequencyName;
public int LensTypeId;
public int LensMaterialId;
}
You need properties, not fields. These are fields:
public ObservableCollection<OphtalboxIA.Lens> RightBestlensList = new ObservableCollection<OphtalboxIA.Lens>();
public ObservableCollection<OphtalboxIA.Lens> LeftBestlensList = new ObservableCollection<OphtalboxIA.Lens>();
As properties, they would look like this:
private readonly ObservableCollection<OphtalboxIA.Lens> _rightList = new ObservableCollection<OphtalboxIA.Lens>();
private readonly ObservableCollection<OphtalboxIA.Lens> _leftList = new ObservableCollection<OphtalboxIA.Lens>();
public ObservableCollection<OphtalboxIA.Lens> RightBestlensList { get { return _rightList; }}
public ObservableCollection<OphtalboxIA.Lens> LeftBestlensList { get { return _leftList; }}
Furthermore, you have a typo in your binding: Source=LefttBestLensList. (One extra "t") And the casing is wrong ("...Lens..." vs. "...lens...").
RightBestlensList and LeftBestlensList must be in ViewModel class and not in Code Behind and they must be a properties.
You have to try below menioned code.
you have to Declare ObservableCollection in your ViewModel Like
private ObservableCollection<Lens> _RightBestLensList = new ObservableCollection<Lens>();
public ObservableCollection<Lens> RightBestLensList
{
get { return _RightBestLensList; }
set { _RightBestLensList = value; RaisePropertyChanged("RightBestLensList"); }
}
Your Lens Class Should be
[XmlInclude(typeof(Lens))]
public class Lens
{
public string LensName { get; set; }
public string LensType { get; set; }
}

Categories