Change data with buttonclick - MVVM - c#

I have a ListView with an List<List<enum>> property and i have a View that shows each bool as button.
I want to cycle through the bound enum when someone clicks on the button. The problem is I cant use a normal click because it would be outside of my ViewModel.
Edit:
I have the class TruthTable that has 2 DynTable:
public sealed class Column<T>
{
public Column()
{
ColumnData = new List<T>();
ColumnHeader = "";
}
...
public List<T> ColumnData { get; set; }
public string ColumnHeader { get; set; }
}
public sealed class DynTable<T>
{
public DynTable()
{
Columns = new List<Column<T>>();
}
...
public List<Column<T>> Columns { get; set; }
}
public sealed class TruthTable
{
public TruthTable()
{
input = new DynTable<bool>();
results = new DynTable<BoolState>();
}
...
private DynTable<bool> input;
private DynTable<BoolState> results;
public DynTable<bool> Input { get { return input; } set { input = value; } }
public DynTable<BoolState> Results { get { return results; }}
}
public enum BoolState
{
False = 0,
True = 1,
DontCare = 2
}
And i have a ViewModel for the TruthTable. I dont think that the I have to show the code for the ViewModel because its just a TruthTable property. I hope thats enough code to understand my problem ._.

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"));

cannot add object to list, add does not exist in current context

I am trying to create a simple radio station class. The RadioPlayer class will store a List of radio stations. Although for some reason I can not add radio stations to a List of radio stations. Can anyone tell me why? It says
"stations.Add does not exist in the current context"
I am also using System.Collections.Generic.
namespace CATest
{
public interface IStreamable
{
}
public enum Genre
{
General,
Music,
News
}
public class RadioStation : IStreamable
{
public const double MinFreq = 87.5;
public const double MaxFreq = 108;
private double frequency;
public string StationName { get; set; }
public Genre Genre { get; set; }
public double Frequency
{
get
{
return frequency;
}
set
{
//validate frequency
if(value > MinFreq && value < MaxFreq)
{
frequency = value;
}
else
{
throw new ArgumentException("Frequency must be between 87.5 and 108");
}
}
}
public override string ToString()
{
return $"Station Name: {StationName} \nStation Genre: {Genre} \nStation Frequency: {Frequency}";
}
}
public class RadioPlayer
{
private List<RadioStation> stations = new List<RadioStation>();
stations.Add(new RadioStation() { Frequency = 100, StationName = "Radio2", Genre = Genre.Music });
}
}
You need to do this inside a method or constructor or somewhere. You cannot place this just within the class declaration.
public void AddStations(RadioStation station)
{
stations.Add(station);
}
you cant add in the class level you must declare method and this method do the behaviour that you need meanwhile you can define the list in class level but any operation should happens inside method or contractor
public class RadioPlayer
{
List<RadioStation> stations = new List<RadioStation>();
public void DoSomething()
{
stations.Add(new RadioStation() { Frequency = 100, StationName = "Radio2", Genre = Genre.Music });
}
}
I would suggest that you do it inside the constructor.
Here's the implementation
public class RadioPlayer
{
public RadioPlayer()
{
stations = new List<RadioStation>();
stations.Add(new RadioStation() { Frequency = 100, StationName = "Radio2", Genre = Genre.Music });
}
private List<RadioStation> stations;
}
You aren't allowed to use Add method at the class context. You can use List initializer to add an item(s) to list at creation time
private List<RadioStation> stations = new List<RadioStation>()
{
new RadioStation() { Frequency = 100, StationName = "Radio2", Genre = Genre.Music }
};

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

How to set values of user control from class

I have a user control and their are many textbox on it. I add this user control to a different project and I can use it, when I write every property on UserControl. I want to set textbox fields of this user control with using a class. These are my codes:
Class:
namespace IEUserControl
{
public class IEValue
{
public string IsEmriNo { get; set; }
public string Nevi { get; set; }
public string BrutKg { get; set; }
public string NetKg { get; set; }
}
}
User Control:
namespace IsEmriUserControl
{
public partial class UC_IsEmri : UserControl
{
public UC_IsEmri()
{
InitializeComponent();
}
//private IsEmriValue _isEmri;
//public IsEmriValue isEmri
//{
// get
// {
// return _isEmri;
// }
// set
// {
// _isEmri = value;
// }
//}
public string IsEmriNo
{
get { return txtIsEmriNo.Text; }
set { txtIsEmriNo.Text = value; }
}
public string Nevi
{
get { return txtNevi.Text; }
set { txtNevi.Text = value; }
}
public string BrutKg
{
get { return txtBrutKg.Text; }
set { txtBrutKg.Text = value; }
}
public string NetKg
{
get { return txtNetKg.Text; }
set { txtNetKg.Text = value; }
}
}
}
When I use properties, I can set textbox values. However I want to set my textbox values with my Class. Can anyone give me an example setting textbox values with using class? Thank you.
Make a method/property like this
public IEValue IE_Value
{
get
{
return new IEValue() {
IsEmrino = txtIsEmriNo.Text,
Nevi = txtNevi.Text,
BrutKg = txtBrutKg.Text,
NetKg = txtNetKg.Text
};
}
set
{
txtIsEmriNo.Text = value.IsEmrino;
txtNevi.Text = value.Nevi;
txtBrutKg.Text = value.BrutKg;
txtNetKg.Text = value.NetKg;
}
}

do not work "set" in some of property in design time

why in desin time do not work set "dataGrid" Property in my code.but property font,with working correct.
I used of this componet on the a Form.(i test it with design time debuging)
enter code here
namespace Example
{
public partial class Component1 : System.Windows.Forms.DataGridView
{
public Component1()
{
}
private DataGridViewColumn _gridcolumn;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[TypeConverter(typeof ( ExpandableObjectConverter))]
public DataGridViewColumn gridcolumn
{
get
{
if (_gridcolumn == null)
_gridcolumn = new DataGridViewColumn();
return _gridcolumn;
}
set //Do not Work Set in designTime
{
_gridcolumn = value;
}
}
private System.Drawing.Font _MyFont;
public System.Drawing.Font MyFont
{
get
{
if (_MyFont == null)
_MyFont = new System.Drawing.Font("tahoma", 8);
return _MyFont;
}
set
{
_MyFont = value; //Work correctly in design time
}
}
int _with;
public int withcustom
{
get
{
return _with;
}
set
{
_with = value; //Work correctly in design time
}
}
}
}
Short Version
Either remove DesignerSerializationVisibility(DesignerSerializationVisibility.Content) from your property, or change it to DesignerSerializationVisibility(DesignerSerializationVisibility.Visible).
Long Version
Applying DesignerSerializationVisibility(DesignerSerializationVisibility.Content) to your property means that the WinForms designer will not generate code that sets the value of the property, but rather code that sets the value of the properties on the value of that property.
For example, say I have these two types:
public class MyControl : Control
{
public class MyControlProperties
{
public string Prop1 { get; set; }
public int Prop2 { get; set; }
}
private MyControlProperties props;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public MyControlProperties Properties
{
get
{
if(props == null) props = new MyControlProperties();
return props;
}
}
}
When the designer generates the code for MyControl on a form, it will look something like this:
myControl.Properties.Prop1 = "foo";
myControl.Properties.Prop2 = 10;
So, instead of setting the value of the Properties property (which, in this code, is read-only; though it doesn't have to be, properties like this usually are), it's setting the values of the properties on the value of that property.
This is good example:
public partial class SCon : UserControl
{
public SCon()
{
InitializeComponent();
if (Persoanas == null)
{
Persoanas = new List<Persoana>();
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<Persoan> Persoanas { get; set; }
}
[Serializable]
public class Persoan
{
public int Id { get; set; }
public String Name { get; set; }
}

Categories