I'm stuck at a problem with MvvmCross.
I don't know how it's suppose to be handled.
The situation:
I have a object called
MyTempClass
It looks like this:
public class MyTempClass
{
public string ImageName { get; set; }
public bool IsTheCorrectAnswer { get; set; }
public bool HasBeenClicked { get; set; }
}
I have a list of MyTempClass.
From this list I iterate and create a view with buttons.
For each button I can successfully pass the object I'm iterating over in a command like this:
for (var i = 0; i < vmExercises.Count; i++) //This is the list...
{
//Create btn & add to the view...
var currentExercise = vmExercises[i];
set.Bind(btn).WithClearBindingKey(currentExercise.ImageName).To(vm => vm.TestCommand).CommandParameter(currentExercise).Apply();
}
The method that TestCommand uses looks like this:
public IMvxCommand TestCommand => new MvxCommand<MyTempClass>(ATestMethod);
private void ATestMethod(MyTempClass obj)
{
obj.HasBeenClicked = true;
CurrentTempClass = obj;
}
The problem
I also want to bind the visibility for the button in this loop.
I've tried like this:
set.Bind(btn).WithClearBindingKey(currentExercise.ImageName).For("Visible").To(vm => vm.ShouldBeVisible).Apply();
ShouldBeVisible looks like this:
public bool ShouldBeVisible
{
get
{
if (CurrentTempClass.IsTheCorrectAnswer && CurrentTempClass.HasBeenClicked)
{
return false;
}
return true;
}
}
The problem is:
If one should be hidden, all of the other buttons gets hidden.
What am I doing wrong? Has anyone else done this?
I'm so thankful for any help! :)
for visibility, you should use the MvvmCross Visibility plugin: https://www.mvvmcross.com/documentation/plugins/visibility
I would also recommend:
Removing logic form your getter and setters.
Call SetProperty() on theVisibility.Set for the Binding to work if the property gets updated.
Related
This is best I could make the question statement. Please be kind.
Here is the situation:
I have a string "InputValues" which contains values in comma seperated format:
chkAwareness1,chkAwareness2,chkAwareness6,chkAwareness9,chkAwareness13...
I need to fill an object with bool value if the name matches with what I have in above string variable.
example:
if InputValues contains "chkAwareness1" then "public bool chkAwareness1" should set to true, otherwise false.
public class SurveyCheckBox
{
public bool chkAwareness1 { get; set; }
public bool chkAwareness2 { get; set; }
public bool chkAwareness3 { get; set; }
public bool chkAwareness4 { get; set; }
public bool chkAwareness5 { get; set; }
public bool chkAwareness6 { get; set; }
public bool chkAwareness7 { get; set; }
.
.
.
}
public void createObjectSurveyCheckBox(string InputValues)
{
string[] ChkValues = InputValues.Split(',');
SurveyCheckBox surveyChkBoxObj = new SurveyCheckBox();
for (int i = 0; i < NumberOfPropertyInSurveyCheckBox ;i++ )
{
// typeof(SurveyCheckBox).GetProperties()[i].Name
}
}
I searched and I found GetProperties method through which I can get the name of property, but I am unable to figure out the logic.. how to search through the values and assign them to bool properties.
Please help.
You're very close. You just need to change your loop, really. The whole method should look like this:
public void CreateObjectSurveyCheckBox(string inputValues)
{
string[] chkValues = inputValues.Split(',');
SurveyCheckBox surveyChkBoxObj = new SurveyCheckBox();
foreach (string value in chkValues)
{
PropertyInfo propInfo = typeof(SurveyCheckBox).GetProperty(value);
if (propInfo != null)
propInfo.SetValue(surveyChkBoxObj, true);
}
}
P.S. You'll notice I took the liberty of changing your capitalization to something much more standard. If you use capitalization like you had, you're likely to get lynched.
I agree with Tim; I would not use something like this in production code.
public void createObjectSurveyCheckBox(string InputValues)
{
var instance = new SurveyCheckBox();
foreach (var property in typeof(SurveyCheckBox).GetProperties().Where(x => x.Name.Contains("chkAwareness")))
{
if (InputValues.Contains(property.Name))
property.SetValue(instance, true);
}
}
I would write the loop from the other direction, from 0 to MaxchkAwareness;
Sort the input first, before going into the loop.
You would also need an index to the next item in your input array (ChkValues), lets call that chkValueIndex;
If the next item in your input array, ChkValues[chkValueIndex], is "chkAwareness"+i.ToString()
then your property is true, and you increment your array pointer .
otherwise your property is false.
But I think you have to use reflection to set the properties in a loop like that, something like this:
Getting a property reference using reflection
I am sure there are better ways to restructure this and do it entirely different, but it sounds to me like you are trying to do the best you can with the system that was given you.
You can try this:
public static void createObjectSurveyCheckBox(string InputValues)
{
string[] ChkValues = InputValues.Split(',');
SurveyCheckBox surveyChkBoxObj = new SurveyCheckBox();
foreach (var prop in typeof(SurveyCheckBox).GetProperties())
{
if (ChkValues.Contains(prop.Name))
prop.SetValue(surveyChkBoxObj, true);
}
}
I have a DataGrid in my View as shown below.,
My Question is how can I Append the values from the textboxes to the row datagrid
I have make sure that the Model has All the properties, When I click on the Add button it overwrites the dataGrid and shows only one latest record the and my ViewModel look like this:
class BatchItemsViewModel : ViewModelBase
{
public SearchItemsModel msearchItems { get; set; }
ObservableCollection<SearchItemsModel> _BatchItemsGrid;
public ObservableCollection<SearchItemsModel> BatchItemsGrid
{
get { return _BatchItemsGrid; }
set
{
_BatchItemsGrid = value;
OnPropertyChanged("BatchItemsGrid");
}
}
private ICommand _addDataToBatchGrid;
public ICommand addDataToBatchGrid
{
get
{
return _addDataToBatchGrid;
}
set
{
_addDataToBatchGrid = value;
}
}
public BatchItemsViewModel()
{
msearchItems = new SearchItemsModel();
addDataToBatchGrid = new RelayCommand(new Action<object>(AddDataInBatchGrid));
}
public void AddDataInBatchGrid(object obj)
{
ObservableCollection<SearchItemsModel> batchGridData = new ObservableCollection<SearchItemsModel>();
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
batchGridData.Add(data);
BatchItemsGrid = batchGridData; // HERE I am overwriting the datagrid
//How can I Append the batchGridData to BatchItemsGrid (BatchItemsGrid.Append(batchGridData)???)
}
}
NOTE: I have gone through the other threads as well in the community for the similar posts but I couldn't find the appropriate and please correct me if I am going in wrong direction.
public void AddDataInBatchGrid(object obj)
{
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
this.BatchItemsGrid.Add(data);
}
...Should do the trick. (don't replace the whole collection, just add items to it and let the notification events handle the UI updates)
I want to Update ListCollectionView in a listbox each time the Item of another ListCollection gets selected.
I have 2 ListViewCollection, SceneCollectionView and ShotCollectionView. I want to have the SceneCollection filtered based on a property SceneNumber in ShotCollectionView, but I can get the ShotCollectionView to update when I go from one item to the other in SceneCollectionView.
This is my ViewModel
public class ShotListViewModel : NotifyUIBase
{
public ListCollectionView SceneCollectionView { get; set; }
private Scenes CurrentScene
{
get { return SceneCollectionView.CurrentItem as Scenes; }
set { SceneCollectionView.MoveCurrentTo(value); RaisePropertyChanged(); }
}
private ObservableCollection<Shot> _allShots = new ObservableCollection<Shot>();
public ObservableCollection<Shot> AllShots
{
get { return _allShots; }
set { _allShots = value; RaisePropertyChanged();}
}
private ListCollectionView _allShotsCollection;
public ListCollectionView AllShotsCollection
{
get
{
if (_allShotsCollection == null)
{
_allShotsCollection = new ListCollectionView(this.AllShots);
_allShotsCollection.Filter = IsSceneNumber;
}
return _allShotsCollection;
}
}
private bool IsSceneNumber(object obj)
{
if (obj as Shot != null
&& (obj as Shot).SceneNumber == (SceneCollectionView.CurrentItem as Scene).SceneNumber)
{
return true;
}
return false;
}
public ShotListViewModel()
{
SceneCollectionView = Application.Current.Resources["SceneCollectionView"] as ListCollectionView;
GetShotList(); //Populates the AllShots Observable collection.
AddShotCommand = new RelayCommand(AddShot);
FilterShotsCommand = new RelayCommand(AddShot);
}
What am I missing here to make it work or is it better to use ICollectionViewLiveShaping. but I have no idea how to implement that
I don`t understand what you tried to do, but lets talk on an example :
Lets say we have
ListBox1 binded to ListBox1Items and
ListBox2 binded to ListBox2Items.
if you want to filter the data from ListBox2 you have to filter ListBox2Items. How to do that ? Is simple : ListBox1 has a property SelectedItem which you can bind to --- lets say --- ListBox1SelectedItem. Every time when selection change, in the setter of the ListBox1SelectedItem you can trigger a filter on ListBox2Items.
Hope you understand what I`ve explained.
I am reading a setting from an XML document, converting it to a string array and then looping through each string and adding them to a DropDownList.
Everything appears to be working fine, until I actually go and look at the DropDownList itself. No matter what I do the DropDownList is empty even though when I am debugging through my code everything appears to be adding itself perfectly.
If anyone could shed a little light on why nothing is displaying despite the fact from the code's point of view it is being populated, I would appreciate it.
My code can be found below (Please note I have also tried populating it via Data Binding but I am still having the same issue.):
public class InstrumentDropDownList : DropDownList
{
public InstrumentDropDownList()
{
PopulateDropDown();
}
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
DropDownList instrumentsDropDown = new DropDownList();
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
instrumentsDropDown.Items.Add(instrument);
}
}
}
}
You're creating a new DropDownList and adding items to it. The problem is, your not doing anything with the new DropDownList you create. You are just adding the items to the wrong list.
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
this.Items.Add(instrument);
}
}
}
As an alternative you should be able to do this as well. You would obviously want to put in some more validation, but this is just to show that you can use the DataSource/DataBind
public void PopulateDropDown()
{
this.DataSource = fabric.SettingsProvider.ReadSetting<string>("Setting.Location").Split(',');
this.DataBind();
}
Why are you creating a new instance of the DropDownList when you are inheriting from the same class. Shouldn't you be doing something like. base.Items.Add() ??
You need to call instrumentsDropDown.DataBind after the foreach statement..
public class InstrumentDropDownList : DropDownList
{
public InstrumentDropDownList()
{
PopulateDropDown();
}
public void PopulateDropDown()
{
string unsplitList = Fabric.SettingsProvider.ReadSetting<string>("Setting.Location");
string[] instrumentList = unsplitList.Split(',');
DropDownList instrumentsDropDown = new DropDownList();
if (instrumentList.Length > 0)
{
foreach (string instrument in instrumentList)
{
instrumentsDropDown.Items.Add(instrument);
}
instrumentsDropDown.DataBind();
}
}
}
I have a ChaseSelection class which i use in casting my dropdown list objects,
now i am trying to put the the values from the database as a default value in the drop down list, but it does not seem to work, can anyone help? I dont even think my loop runs. Here is my chaseselection class, and also put in the loop below: Thanks
public class ChaseSelectionItems
{
public string code { get; set; }
public string text { get; set; }
public ChaseSelectionItems(string code, string text)
{
this.code = code;
this.text = text;
}
public override string ToString()
{
return this.text;
}
}
foreach (ChaseSelectionItems items in drpdwnChaseSecSelection.Items)
{
if (items.code == _Row.xcs_View)
{
drpdwnChaseSecSelection.SelectedValue = items.text;
}
}
It is not entirely clear how you configured the listbox but most likely you did not configure ValueMember correctly. The following might fix that:
foreach (ChaseSelectionItems items in drpdwnChaseSecSelection.Items)
{
if (items.code == _Row.xcs_View)
{
// drpdwnChaseSecSelection.SelectedValue = items.text;
drpdwnChaseSecSelection.SelectedItem = items;
}
}