I'm building a Mango app that writes data to a SqlCe database; I have a ListBox bound to a DataSource that must show items when they are added to the database, but when I add/update data I cannot get updates and they are only shown when I reload the page.
Here are some snippets:
public class TimeTrackerViewModel: INotifyPropertyChanged, INotifyPropertyChanging
{
private List<TimeItems> _timeItems;
public List<TimeItems> TimeItems
{
get { return _timeItems; }
set
{
NotifyPropertyChanging("TimeItems");
_timeItems = value;
NotifyPropertyChanged("TimeItems");
}
}
public void LoadCollectionsFromDatabase()
{
// Specify the query for all to-do items in the database.
var times = from t in db.Times
select new TimeItems
{
DtIn = t.DtIn,
DtOut = t.DtOut,
Id = t.Id
};
// Query the database and load all to-do items.
TimeItems = new List<TimeItems>(times);
}
.....
.....
}
When I add data to the Times table I don't see db updates to the listBox bound to the TimeItems collection.
What am I doing wrong?
Make TimeItems an ObservableCollection
Related
Data is a generic List of domain objects.
I click the "Deploy Status" column header to sort on that column.
I have a button that does nothing more than folv.UpdateObject(someObject) .
Every time I press that button, the Deploy Status column maintains its sort, but all rows within the sorted blocks are randomly reordered, as per screenshot.
I have commented out everything in the form's code beyond loading the data, the test button, and the FastObjectListView's column.Add() and .SetObjects(). There are no event handlers wired up for the FastObjectListView. I am not setting PrimarySort or SecondarySort in code; only by clicking with the mouse.
You should be able to fix this problem by either calling Sort after your button's call to UpdateObject or changing your usage of UpdateObject to RefreshObject
Reproducing the problem (C# Repro for the issue in the API)
This seems to reproduce the problem you are having. Run the code, sort the Other column ascending. Click the update button.
public class MainForm : Form
{
public MainForm()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(300, 300);
this.Name = "MainForm";
this.ResumeLayout(false);
this.PerformLayout();
var OLVa = new FastObjectListView();
OLVa.Width = 250;
OLVa.Height = 250;
OLVa.Columns.Add(new OLVColumn("ID", "ID"));
OLVa.Columns.Add(new OLVColumn("Other", "Other"));
var l1 = new lolz(1, 3);
OLVa.AddObject(l1);
OLVa.AddObject(new lolz(2,3));
this.Controls.Add(OLVa);
var btn = new Button()
{
Text = "Update",
Top = OLVa.Bottom
};
btn.Click += (s,e)=>OLVa.UpdateObject(l1);
this.Controls.Add(btn);
}
private class lolz
{
public int ID;
public int Other;
public lolz(int id, int other)
{
ID = id;
Other = other;
}
}
}
Fixing the problem
The following would fix it for the above example:
btn.Click += (s,e)=>
{
OLVa.BeginUpdate();
try
{
OLVa.UpdateObject(l1);
OLVa.Sort();
}
finally
{
OLVa.EndUpdate();
}
};
I have a RecyclerView with an AAC in my Fragment.
ViewModel --> Repository --> DAO with some custom Queries and a getAllItems.
I want to use a Filter FAB or a Spinner to call getOrderItemList or getWhereItemList queries but i dont know how must i do it.
I have a Repository Filter for my SearchView but is a different thing, now i want to change list order (alphabetical, year...) and create a WhereCondition with a lot of checkbox that i have in a Dialog (example: i check "complete" and "Action" checkbox and creates the String whereCondition = "(status = 'complete' and genre like '%Action%')" ).
How can i call getWhereItemList and getOrderItemList queries from my Fragment to change my RecyclerView content?
ItemDAO:
#Query("SELECT * from item_table ")
<List<Item>> getItemList();
#Query("SELECT * from item_table ORDER by :order DESC")
<List<Item>> getOrderItemList(String order);
#Query("SELECT * from item_table WHERE :whereCondition")
<List<Item>> getWhereItemList(String whereCondition);
My Fragment fills the RecyclerView with getAllItems:
private ItemViewModel myItemViewModel;
RecyclerView myRecyclerView = findViewById(R.id.recyclerview);
final ItemListAdapter myAdapter = new ItemListAdapter(this);
myRecyclerView.setAdapter(myAdapter);
myRecyclerView.setLayoutManager(new LinearLayoutManager(this));
myItemViewModel = ViewModelProviders.of(this).get(ItemViewModel.class);
myItemViewModel.getAllItems().observe(this, new Observer<List<Item>>() {
#Override
public void onChanged(#Nullable final List<Item> items) {
myAdapter.setItems(items);
}
ItemListAdapter:
private List<Item> myItems;
void setItems(List<Item> items){
myItems = items;
notifyDataSetChanged();
}
ItemViewModel:
private ItemRepository myRepository;
private LiveData<List<Item>> myAllItems;
public ItemViewModel (Application application) {
super(application);
myRepository = new ItemRepository(application);
myAllItems = myRepository.getAllItems();
}
LiveData<List<Item>> getAllItems() { return myAllItems; }
Thanks.
The idea is to have two LiveData instances:
one that keeps track of the current filter type. You may set its initial value.
one that emits List<Item>. This also should react to the other LiveData change and get new List<Item> if necessary.
You can use Transformations.SwitchMap to implement LiveData2. What it does is it basically returns a LiveData instance that can switch to a different source in response to another LiveData object.
ItemViewModel:
private ItemRepository myRepository;
/**
* Keep track of the current filter type.
* In this example the initial value is set to Filter.ALL, which
* represents the non-filtered list.
*/
private MutableLiveData<Filter> itemFilter = new MutableLiveData<>(Filter.ALL);
/**
* Emits list of items
*/
private LiveData<List<Item>> myItems = Transformations.switchMap(itemFilter, filter -> {
// Everytime itemFilter emits a new value, this piece of code
// will be invoked. You are responsible for returning the
// LiveData instance according to the filter value.
switch(filter.type) {
case ALL:
return myRepository.getAllItems();
case ORDER_BY:
return myRepository.getOrderItemList(filter.query);
case WHERE:
return myRepository.getWhereItemList(filter.query);
}
});
public ItemViewModel (Application application) {
super(application);
myRepository = new ItemRepository(application);
}
public LiveData<List<Item>> getItems() { return myItems; }
/**
* View should call this method in order to switch to different
* filter.
*/
public void changeFilter(Filter itemFilter) {
this.itemFilter.setValue(filter);
}
Define this custom filter class:
public class Filter {
public enum Type {
ALL,
ORDER_BY,
WHERE
}
final public Type type;
final public String query;
public Filter(Type type, String query) {
this.type = type;
this.query = query;
}
}
I are using umbraco 7.
I want to create a drop down list of members (From MSSql) on the front page of my site.
I have a nuPicker Sql Dropdown setup in datatypes and can load this in the back office fine.
Now I want to get it on the front screen.
Once there it needs to load a whole heap of custom information.
Before changing needs to test custom information and warn if needs to be saved because of changes.
Who do I do this
Worked it out.
Don't use nuPicker
public IEnumerable<Some Model> GetData()
{
var db = applicationContext.Current.Database.Database;
var tbl = db.Fetch<Some Model>(#" Some Sql Script ");
return tbl;
}
public List<SelectListItem> BuildDropDown()
{
List<SelectListItem> lst = new List<SelectListItem>
IEnumerable< Some Model> Members = GetData();
for each item in Members)
{
lst.Add(new SelectListItem { Value = item.Label, Text = item.Label });
}
}
I have below statement:
return Redirect(this.Request.UrlReferrer.AbsolutePath);
this redirects to the caller view. It is working ok, but now I need to return a view model when redirecting, something like this (it's wrong):
return Redirect(this.Request.UrlReferrer.AbsolutePath(item));
So how can I achieve this?
I want to do this because I have a jqrid in which one of its columns offers some actions, edit and delete the row. So if user clicks on edit, i retrieve some data from the id passed to the database. Then once I get this data, I populate a view model in order to update some textboxes in the view, so I need to pass the view model when redirecting.
Below my code in the controller:
public ActionResult Edit(int id)
{
ItemViewModel item = new ItemViewModel();
using (DBContext context = new DBContext())
{
Items itemToModify = context.Items.Single(i=> i.ItemId == id);
item.Desc = itemToModify.Desc;
item.Name = itemToModify.Name;
}
return Redirect(this.Request.UrlReferrer.AbsolutePath, item); <-- how to do this
}
You can use TempData like
In your controller
public ActionResult Action1()
{
ItemViewModel item = new ItemViewModel();
TempData["item"] = item;
return Redirect("Action2");
}
public ActionResult Action2()
{
ItemViewModel item = (ItemViewModel)TempData["item"];
//Your Code
}
I've been working towards a solution for some time and could use a little help. I know I've seen an example of this before, but tonight I cannot find anything close to what I need.
I have a service that provides me all my DropDownLists, either from Cache or from the DomainService. They are presented as IEnumerable, and are requested from the a repository with GetLookup(LookupId).
I have created a custom attribute that I have decorated my MetaDataClass that looks something like this:
[Lookup(Lookup.Products)]
public Guid ProductId
I have created a custom Data Form that is set to AutoGenerateFields and I am intercepting the autogenerate fields.
I am checking for my CustomAttribute and that works.
Given this code in my CustomDataForm (standard comments removed for brevity), what is the next step to override the field generation and place a bound combobox in its place?
public class CustomDataForm : DataForm
{
private Dictionary<string, DataField> fields = new Dictionary<string, DataField>();
public Dictionary<string, DataField> Fields
{
get { return this.fields; }
}
protected override void OnAutoGeneratingField(DataFormAutoGeneratingFieldEventArgs e)
{
PropertyInfo propertyInfo = this.CurrentItem.GetType().GetProperty(e.PropertyName);
foreach (Attribute attribute in propertyInfo.GetCustomAttributes(true))
{
LookupFieldAttribute lookupFieldAttribute = attribute as LookupFieldAttribute;
if (lookupFieldAttribute != null)
{
// Create a combo box.
// Bind it to my Lookup IEnumerable
// Set the selected item to my Field's Value
// Set the binding two way
}
}
this.fields[e.PropertyName] = e.Field;
base.OnAutoGeneratingField(e);
}
}
Any cited working examples for SL4/VS2010 would be appreciated.
Thanks
Update - Here's where I am at. I get my combo now, but it's always empty even though itemsSource is not.
if (lookupFieldAttribute != null)
{
ComboBox comboBox = new ComboBox();
Binding newBinding = e.Field.Content.GetBindingExpression(TextBox.TextProperty).ParentBinding.CreateCopy();
newBinding.Mode = BindingMode.TwoWay;
newBinding.Converter = new LookupConverter(lookupRepository);
newBinding.ConverterParameter = lookupFieldAttribute.Lookup.ToString();
comboBox.SetBinding(ComboBox.SelectedItemProperty,newBinding);
comboBox.ItemsSource = lookupRepository.GetLookup(lookupFieldAttribute.Lookup);
e.Field.Content = comboBox;
}
I found a solution.
if (lookupFieldAttribute != null)
{
ComboBox comboBox = new ComboBox();
Binding newBinding = e.Field.Content.GetBindingExpression(TextBox.TextProperty).ParentBinding.CreateCopy();
var itemsSource = lookupRepository.GetLookup(lookupFieldAttribute.Lookup);
var itemsSourceBinding = new Binding { Source = itemsSource };
comboBox.SetBinding(ItemsControl.ItemsSourceProperty, itemsSourceBinding);
newBinding.Mode = BindingMode.TwoWay;
newBinding.Converter = new LookupConverter(lookupRepository);
newBinding.ConverterParameter = lookupFieldAttribute.Lookup.ToString();
comboBox.SetBinding(ComboBox.SelectedItemProperty,newBinding);
e.Field.Content = comboBox;
}