How to update list view from another class in Xamarin forms? - class

I have created a list view in one class and called delete method from another class. Listview getting call but not updating list view if i call from another class. But its getting update when i call inside the same class. How to solve this issue?
namespace New
{
public partial class WishesPage : ContentPage
{
ListView listView = new ListView();
public WishesPage()
{
InitializeComponent();
var arr = JToken.Parse(ids);
foreach (var ite in arr.Children())
{
var itemProperties = ite.Children<JProperty>();
string contactElement = itemProperties.FirstOrDefault(x => x.Name == "contact").Value.ToString();
sample.Add(contactElement);
}
listView.ItemTemplate = new DataTemplate(typeof(CustomListCell));
listView.ItemsSource = sample;
Content = new StackLayout
{
Children =
{
listView,
}
};
}
public async Task delete(string wishid)
{
indicator.IsRunning = true;
var client = new HttpClient();
client.BaseAddress = new Uri("http:……”);
if (response == "success")
{
listView.ItemsSource = null;
listView.ItemsSource = sample;
}
}
}
public class CustomListCell : ViewCell
{
public CustomListCell()
{
wishIdLabel.SetBinding(Label.TextProperty, new Binding("contact"));
horizontalLayout.Children.Add(wishIdLabel);
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true };
deleteAction.Clicked += async (sender, e) =>
{
WishesPage wishes = new WishesPage();
wishes.delete(wishId);
};
ContextActions.Add(deleteAction);
}
}
}

I have updated this repo that explain how to use Commands inside a ViewCell.
In your case, you should move the construction of ViewCell inside the ContentPage. Something like
lv.ItemTemplate = new DataTemplate(() =>
{
StackLayout slView = new StackLayout();
Label lDesc = new Label();
lDesc.SetBinding(Label.TextProperty, "Description", stringFormat: "DESCRIPTION: {0}");
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.TrashCommand", source: this));
deleteAction.SetBinding(MenuItem.CommandParameterProperty, ".");
slView.Children.Add(lDesc);
ViewCell vc = new ViewCell() {View = slView };
vc.ContextActions.Add(deleteAction);
return vc;
}
Now, when you longpress the row, a ContextAction "Delete" appears and a TrashCommand in your ViewModel is executed (you should use MVVM...), a "these" parameter is passed (the selected obj) so you can delete it from the List
this.TrashCommand = new Command(async (object obj) => {
try
{
if (_isTapped)
return;
if (obj != null)
System.Diagnostics.Debug.WriteLine("Obj is not null");
else
System.Diagnostics.Debug.WriteLine("Obj IS null");
_isTapped = true;
var ret = await Application.Current.MainPage.DisplayAlert("Attention", "Delete this row?", "Yes", "No");
if (ret)
{
// List is your "sample" list... Removing the obj, is it reflected to ListView if you use ObservableCollection instead of List
List.Remove((Model)obj);
Count = List.Count;
}
_isTapped = false;
}
catch (Exception ex) {
_isTapped = false;
await Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
}
});
}

Related

How do I populate Items in collection view from model view if I am using file picker?

I am trying to select some files from file picker . Once I select them I want to show them in my collection view. If I am trying to achieve this thing from code behind then it is working fine but if I am trying it from MVVM then it is not populating the files I have selected.
and the reason I am trying to do it with MVVM is that I want to navigate to the next page with all selected files.
Thanks.
Here is my code:
MainPage.xaml
<CollectionView Grid.ColumnSpan="2" Grid.Row="1"
SelectionMode="Single" x:Name="myCollection"
VerticalOptions="FillAndExpand"
VerticalScrollBarVisibility="Always"
ItemTemplate="{StaticResource appDataTemplate}"
ItemsSource="{Binding Items}">
</CollectionView>
Here I have binded my context.
MainPage.Xaml.cs
public MainPage(FileViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
And this is my viewModel:`[ObservableProperty]
List sourceData;
public List<Item> Items
{
get { return sourceData; }
set
{
sourceData = value;
}
}
public FileViewModel(IFolderPicker folderPicker)
{
sourceData = Items ;
_folderPicker = folderPicker;
}`
public async void Add_File(object sender, EventArgs e)
{
var CustomFileType = new FilePickerFileType(new Dictionary<DevicePlatform,
IEnumerable<String>>
{
//logic
});
var results = await FilePicker.PickMultipleAsync(new PickOptions
{
FileTypes = CustomFileType,
});
sourceData = null;
foreach (var result in results)
{
FileInfo fileInfo = new FileInfo(result.FullPath);
double size = fileSize(fileInfo);
bool fileExist = false;
if (Items != null)
{
foreach (Item item in Items)
{
if (item.FilePath.Equals(result.FullPath))
{
fileExist = true;
break;
}
}
}
else
{
Items= new ObservableCollection<Item>();
}
if (!fileExist)
{
Items.Add(new Item
{
FilePath = result.FullPath,
FileSize = size
});
}
else
{
Items= sourceData;
// await DisplayAlert("Alert", "File already exist!", "Ok");
}
}
Items = sourceData;
}
Same code is working file if I put the view models code in code behind like below:
private async void Add_File(object sender, EventArgs e)
{
var CustomFileType = new FilePickerFileType(new Dictionary<DevicePlatform,
IEnumerable<String>>
{
{ DevicePlatform.WinUI, new[]{"ics"} },
});
var results = await FilePicker.PickMultipleAsync(new PickOptions
{
FileTypes = CustomFileType,
});
myCollection.ItemsSource = null;
foreach (var result in results)
{
FileInfo fileInfo = new FileInfo(result.FullPath);
double size = fileSize(fileInfo);
bool fileExist = false;
foreach (Item item in Items)
{
if (item.FilePath.Equals(result.FullPath))
{
fileExist = true;
break;
}
}
if (!fileExist)
{
Items.Add(new Item
{
FilePath = result.FullPath,
FileSize = size
});
}
else
{
myCollection.ItemsSource = Items;
await DisplayAlert("Alert", "File already exist!", "Ok");
}
}
myCollection.ItemsSource = Items;
}
But it is not working with file view model.
I am not able to populate the collection view from view model.

moq mongodb InsertOneAsync method

I am using Mongodb database with .net core. I just want to moq insert method that using mongodbContext. Here is what I am trying to do but it's not working:
public void InsertEventAsync_Test()
{
//Arrange
var eventRepository = EventRepository();
var pEvent = new PlanEvent
{
ID = "testEvent",
WorkOrderID = "WorkOrderID",
IsDeleted = false,
IsActive = true,
EquipmentID = "EquipmentID"
};
////Act
//mockEventContext.Setup(mr => mr.PlanEvent.InsertOne(It.IsAny<PlanEvent>(), It.IsAny<InsertOneOptions>()))
mockEventContext.Setup(s => s.PlanEvent.InsertOneAsync(It.IsAny<PlanEvent>(), It.IsAny<InsertOneOptions>())).Returns("sdad");
var result = eventRepository.InsertEventAsync(pEvent);
////Assert
result.Should().NotBeNull();
}
Below is the method that I need to Moq:
public EventRepository(IFMPContext eventContext)
{
_eventContext = eventContext;
}
public async Task<string> InsertEventAsync(Model.EventDataModel.PlanEvent eventobj)
{
eventobj._id = ObjectId.GenerateNewId();
eventobj.CreatedDateTime = DateTime.UtcNow.ToString();
try
{
_eventContext.PlanEvent.InsertOne(eventobj);
return eventobj.ID;
}
catch (Exception ex)
{
string x = ex.Message;
}
return "";
}
Assuming
public class EventRepository {
private readonly IFMPContext eventContext;
public EventRepository(IFMPContext eventContext) {
this.eventContext = eventContext;
}
public async Task<string> InsertEventAsync(Model.EventDataModel.PlanEvent eventobj) {
eventobj._id = ObjectId.GenerateNewId();
eventobj.CreatedDateTime = DateTime.UtcNow.ToString();
try {
await eventContext.PlanEvent.InsertOneAsync(eventobj);
return eventobj.ID;
} catch (Exception ex) {
string x = ex.Message;
}
return "";
}
}
You need to configure the test to support the async nature of the method under test
public async Task InsertEventAsync_Test()
{
//Arrange
var expected = "testEvent";
var pEvent = new PlanEvent {
ID = expected,
WorkOrderID = "WorkOrderID",
IsDeleted = false,
IsActive = true,
EquipmentID = "EquipmentID"
};
var mockEventContext = new Mock<IFMPContext>();
mockEventContext
.Setup(_ => _.PlanEvent.InsertOneAsync(It.IsAny<PlanEvent>(), It.IsAny<InsertOneOptions>()))
.ReturnsAsync(Task.FromResult((object)null));
var eventRepository = new EventRepository(mockEventContext.Object);
//Act
var actual = await eventRepository.InsertEventAsync(pEvent);
//Assert
actual.Should().NotBeNull()
actual.Should().Be(expected);
}
The test method definition needed to be updated to be asynchronous to allow the method under test to be awaited. The mock dependency also needed to be setup in such a way to allow the async flow to continue as expected when invoked.
#Nkosi Thanks a lot for your help. Finally i found the way. i was missing extra moq param It.IsAny<System.Threading.CancellationToken>() below is the working test
public void InsertEventAsync_Test()
{
//Arrange
var eventRepository = EventRepository();
var pEvent = new PlanEvent
{
ID = "testEvent",
WorkOrderID = "WorkOrderID",
IsDeleted = false,
IsActive = true,
EquipmentID = "EquipmentID"
};
////Act
mockEventContext.Setup(s => s.PlanEvent.InsertOne(It.IsAny<PlanEvent>(), It.IsAny<InsertOneOptions>(),It.IsAny<System.Threading.CancellationToken>()));
var result = eventRepository.InsertEventAsync(pEvent);
////Assert
result.Should().NotBeNull();
Assert.AreEqual(pEvent.ID, result);
}

Add OR condition to query

I am wondering how it is possible to add an OR condition to the Envers criteria api:
public IEnumerable<Guid> GetHistory(object id, params string[] props)
{
var auditQuery = AuditReaderFactory.Get(Session).CreateQuery()
.ForRevisionsOfEntity(typeof(T), false, true);
foreach (var prop in props)
{
auditQuery.Add(AuditEntity.RelatedId(prop).Eq(id)); // <-- adds AND, while OR is required!
}
return auditQuery
.GetResultList<object[]>()
.Select(i => ((T)i[0]).ID)
.Distinct();
}
Use AuditEntity.Disjunction().
In your example, something like...
[..]
var disjunction = AuditEntity.Disjunction();
foreach (var prop in props)
{
disjunction.Add(AuditEntity.RelatedId(prop).Eq(id));
}
auditQuery.Add(disjunction);
[..]
I did like this in Java as #Roger mentioned above. (Just in case if anybody needs)
public List<Employee> getAuditHistory(Session session, int id, String property) {
AuditReader auditReader = AuditReaderFactory.get(session);
List<Employee> employeeHistory = new ArrayList<>();
if (auditReader != null) {
AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(Employee.class, true, false)
.add(AuditEntity.property(ResultsConstants.Employee_ID).eq(id));
AuditDisjunction auditDisjunction = null;
if (property.equalsIgnoreCase("FULL_NAME")) {
auditDisjunction = AuditEntity.disjunction().add(AuditEntity.property("FIRST_NAME".toUpperCase()).hasChanged())
.add(AuditEntity.property("LAST_NAME".toUpperCase()).hasChanged());
} else {
auditQuery = auditQuery.add(AuditEntity.property(property.toUpperCase()).hasChanged());
}
auditQuery = auditQuery.addOrder(AuditEntity.property("MODIFIED_DATE").desc());
if(null != auditDisjunction){
auditQuery = auditQuery.add(auditDisjunction);
}
if (auditQuery != null) {
if (auditQuery.getResultList().isEmpty()) {
// Log here or throw it back to caller
}
employeeHistory.addAll(auditQuery.getResultList());
}
}
return employeeHistory;
}

Replace bookmark contents in Word using OpenXml

I can't find any working code examples for replacing bookmark contents. The code should be able to handle both the case replace empty bookmark and replace bookmark with preexisting content.
For example: If I have this text in a Word document:
"Between the following periods comes Bookmark1.. Between next periods comes Bookmark2.."
and I want to insert the text "BM1" between the first periods, and "BM2" between the next.
After the first replacement run, the replacements are inserted correctly.
But after the next replacement run, all of the text on the line after Bookmark1 gets deleted, and then the replacement for Bookmark2 gets inserted.
This is my c# code:
var doc = WordprocessingDocument.Open(#"file.docx", true);
public static Dictionary<string, wd.BookmarkStart> FindAllBookmarksInWordFile(WordprocessingDocument file)
{
var bookmarkMap = new Dictionary<String, wd.BookmarkStart>();
foreach (var headerPart in file.MainDocumentPart.HeaderParts)
{
foreach (var bookmarkStart in headerPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
}
foreach (var bookmarkStart in file.MainDocumentPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
return bookmarkMap;
}
/*extension methods*/
public static bool IsEndBookmark(this OpenXmlElement element, BookmarkStart startBookmark)
{
return IsEndBookmark(element as BookmarkEnd, startBookmark);
}
public static bool IsEndBookmark(this BookmarkEnd endBookmark, BookmarkStart startBookmark)
{
if (endBookmark == null)
return false;
return endBookmark.Id.Value == startBookmark.Id.Value;
}
/* end of extension methods */
public static void SetText(BookmarkStart bookmark, string value)
{
RemoveAllTexts(bookmark);
bookmark.Parent.InsertAfter(new Run(new Text(value)), bookmark);
}
private static void RemoveAllTexts(BookmarkStart bookmark)
{
if (bookmark.ColumnFirst != null) return;
var nextSibling = bookmark.NextSibling();
while (nextSibling != null)
{
if (nextSibling.IsEndBookmark(bookmark) || nextSibling.GetType() == typeof(BookmarkStart))
break;
foreach (var item in nextSibling.Descendants<Text>())
{
item.Remove();
}
nextSibling = nextSibling.NextSibling();
}
}
I have looked around a long time for a general solution.
Any help is appreciated! -Victor
Maybe this can help you
first:delete bookmarkContent
second:find bookMark => insert value
public static void InsertTest1(WordprocessingDocument doc, string bookMark, string txt)
{
try
{
RemoveBookMarkContent(doc, bookMark);
MainDocumentPart mainPart = doc.MainDocumentPart;
BookmarkStart bmStart = findBookMarkStart(doc, bookMark);
if (bmStart == null)
{
return;
}
Run run = new Run(new Text(txt));
bmStart.Parent.InsertAfter<Run>(run, bmStart);
}
catch (Exception c)
{
//not Exception
}
}
public static void RemoveBookMarkContent(WordprocessingDocument doc, string bmName)
{
BookmarkStart bmStart = findBookMarkStart(doc, bmName);
BookmarkEnd bmEnd = findBookMarkEnd(doc, bmStart.Id);
while (true)
{
var run = bmStart.NextSibling();
if (run == null)
{
break;
}
if (run is BookmarkEnd && (BookmarkEnd)run == bmEnd)
{
break;
}
run.Remove();
}
}
private static BookmarkStart findBookMarkStart(WordprocessingDocument doc, string bmName)
{
foreach (var footer in doc.MainDocumentPart.FooterParts)
{
foreach (var inst in footer.Footer.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var header in doc.MainDocumentPart.HeaderParts)
{
foreach (var inst in header.Header.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var inst in doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
{
if (inst is BookmarkStart)
{
if (inst.Name == bmName)
{
return inst;
}
}
}
return null;
}
This code works but not when the bookmark is placed within a field/formtext (a gray box).
private static void SetNewContents(wd.BookmarkStart bookmarkStart, string text)
{
if (bookmarkStart.ColumnFirst != null) return;
var itemsToRemove = new List<OpenXmlElement>();
var nextSibling = bookmarkStart.NextSibling();
while (nextSibling != null)
{
if (IsEndBookmark(nextSibling, bookmarkStart))
break;
if (nextSibling is wd.Run)
itemsToRemove.Add(nextSibling);
nextSibling = nextSibling.NextSibling();
}
foreach (var item in itemsToRemove)
{
item.RemoveAllChildren();
item.Remove();
}
bookmarkStart.Parent.InsertAfter(new wd.Run(new wd.Text(text)), bookmarkStart);
}

Monotouch: Need to add navigation item(BarButtonItem) and event in every page

Hi i am very new to iphone programming..i have used DialogViewController in my application.
In the following code , addButton.Clicked event will generate an new root element with sections(Table cell) and we can navigating to another page using these sections.
i need NavigationItem(RightBarButtonItem) and its event in every navigating pages to save the datas in current page
its very urgent!
Thanks.
Part of My Code:
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow _window;
UINavigationController _nav;
DialogViewController _RootVC;
RootElement _rootElement;
UIBarButtonItem _addButton;
UIBarButtonItem _EditButton;
DataBaseAccess da =new DataBaseAccess();
public string _name;
EntryElement StrainName;
//Load all the datas
private bool LoadMain()
{
_window = new UIWindow (UIScreen.MainScreen.Bounds);
_rootElement = new RootElement("Strain")
{
new Section()
{
(StrainName = new EntryElement ("Strain Name","Enter Name",""))
},
new Section()
{
}
};
List ();
_RootVC = new DialogViewController (UITableViewStyle.Grouped,_rootElement,true);
_nav = new UINavigationController(_RootVC);
//_EditButton= new UIBarButtonItem(UIBarButtonSystemItem.Edit);
_EditButton = new UIBarButtonItem("Delete", UIBarButtonItemStyle.Plain,null);
_addButton = new UIBarButtonItem(UIBarButtonSystemItem.Add);
_RootVC.NavigationItem.LeftBarButtonItem = _EditButton;
_RootVC.NavigationItem.RightBarButtonItem = _addButton;
_addButton.Clicked += (sender, e) =>
{
if (StrainName.Value=="")
{
return ;
}
da.Addnew (StrainName.Value);
var strain = new Strains{Name = StrainName.Value};
var strainElement = new RootElement(StrainName.Value)
{
new Section()
{
new StringElement("Name",strain.Name)
},
new Section()
{
new EntryElement("Strain Type"," Enter Type","")
},
new Section()
{
new RootElement("Dispensory")
{
new Section()
{
new EntryElement("Dispensory"," Enter Dispensory name","")
},
new Section()
{
new EntryElement("Address"," Enter Address","")
},
new Section()
{
new EntryElement("City","Enter City","")
},
new Section()
{
new EntryElement("State","Enter State","")
},
new Section()
{
new EntryElement("Zip","Enter Zip","")
},
new Section()
{
new EntryElement("Phone","Enter Phone","")
}
}
},
new Section()
{
new EntryElement("Price","Enter Price per Gram","")
},
new Section()
{
new EntryElement("Rating","Enter Rating 1-10","")
}
};
StrainName.Value = "";
_rootElement[0].Add(strainElement);
};
_EditButton.Clicked += (sender, e) =>
{
Edit_Elements();
};
_window.RootViewController = _nav;
_window.MakeKeyAndVisible ();
return true;
}
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
return LoadMain ();
}
//List the data from DB
private void List (){
DataBaseAccess Lobj_da=new DataBaseAccess();
Lobj_da.getstrains ();
List<string> strains=Lobj_da.Starins;
foreach (string name in strains)
{
var strain = new Strains{Name = name};
var strainElement = new RootElement(name)
{
new Section()
{
new EntryElement("Name",strain.Name,strain.Name)
},
new Section()
{
new EntryElement("Strain Type"," Enter Type","")
},
new Section()
{
new RootElement("Dispensory")
{
new Section()
{
new EntryElement("Dispensory"," Enter Dispensory name","")
},
new Section()
{
new EntryElement("Address"," Enter Address","")
},
new Section()
{
new EntryElement("City","Enter City","")
},
new Section()
{
new EntryElement("State","Enter State","")
},
new Section()
{
new EntryElement("Zip","Enter Zip","")
},
new Section()
{
new EntryElement("Phone","Enter Phone","")
}
}
},
new Section()
{
new EntryElement("Price","Enter Price per Gram","")
},
new Section()
{
new EntryElement("Rating","Enter Rating 1-10","")
}
};
StrainName.Value = "";
_rootElement[0].Add(strainElement);
}
}
//
//Edit Changes
void ConfigEdit (DialogViewController dvc)
{
//dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Edit, delegate {
dvc.NavigationItem.LeftBarButtonItem = new UIBarButtonItem("Update", UIBarButtonItemStyle.Plain,null);
dvc.TableView.SetEditing (true, true);
ConfigDone (dvc);
// });
}
void ConfigDone (DialogViewController dvc)
{
dvc.NavigationItem.RightBarButtonItem = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
dvc.TableView.SetEditing (false, true);
ConfigEdit (dvc);
LoadMain();
});
}
public void Edit_Elements ()
{
RootElement _rootElement_Edit;
_rootElement_Edit = new RootElement("Strain")
{
new Section()
{
}
};
DataBaseAccess LEobj_da=new DataBaseAccess();
LEobj_da.getstrains ();
List<string> strains=LEobj_da.Starins;
foreach (string name in strains){
var strain = new Strains{Name = name};
var strainElement = new RootElement(name)
{
new Section()
{
new StringElement("Name",strain.Name)
}
};
_rootElement_Edit[0].Add(strainElement);
}
var dvc = new EditingDialog (_rootElement_Edit, true);
ConfigEdit (dvc);
_nav.PushViewController (dvc, true);
}
} `
I think the best way is the create a new DialogViewController and to implement your saving code there.
You should subclass UINavigationView and all your views should inherit form it