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

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.

Related

How to get list from docx file?

How to determine whether a list is bulleted or numbered? I use OpenXML
In general, what will be the list determines NumberingDefinitionsPart, I thought to find out the Numbering of a certain element, but this method did not work
I am processing the list in the recommended way, but I need to know which way it is
`public void ParagraphHandle(Elements.Paragraph paragraph, StringBuilder text)
{
var docPart = paragraph.DocumentPart;
var element = paragraph.Element;
var r = element.Descendants<Numbering>().ToArray();
var images = GetImages(docPart, element);
if (images.Count > 0)
{
foreach (var image in images)
{
if (image.Id != null)
{
string filePath = _saveResources.SaveImage(image);
_handler.ImageHandle(filePath, text);
}
}
return;
}
var paragraphProperties = element.GetFirstChild<ParagraphProperties>();
var numberingProperties = paragraphProperties?.GetFirstChild<NumberingProperties>();
if (numberingProperties != null)
{
var numberingId = numberingProperties.GetFirstChild<NumberingId>()?.Val?.Value;
if (numberingId != null && !paragraph.IsList)
{
text.AppendLine("<ul>");
paragraph.IsList = true;
paragraph.List = new List();
_htmlGenerator.GenerateList(paragraph, text);
}
else
{
_htmlGenerator.GenerateList(paragraph, text);
}
}
else
{
if (paragraph.IsList)
{
text.AppendLine("</ul>");
paragraph.IsList = false;
}
_handler.ParagraphHandle(element, text);
}
}`

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

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

Get image files from Local Folder to display in the UI at runtime fails

I used below codes to retrieve image files from LocalFolder
Total images files is 20 in LocalFolder
The problem:
Only 8 images are displayed and the rest is blank.
Why the rest can not be displayed?
Can bind the BitmapImage file to the image Control as below base on MVVM ?
Example : imageURL ="ms-appdata:///local/imgfile.jpg"
---- In XAML : PhotoView.xaml
<Image x:Name="Img" Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
<TextBlock FontSize="23" Text="{Binding Unit_Price}" Height="23" Margin="3,1,3,0"/>
<TextBlock FontSize="23" Text="{Binding Description}" Height="23" Width="300" Margin="1,1,1,0/>
--- In code behind: PhotoView
ItemsViewModel itemsViewModel = null;
ObservableCollection items = null;
itemsViewModel = new ItemsViewModel();
items = itemsViewModel.GetItems();
//-- GridViewControl
ItemsViewSource.Source = items;
ItemsGridView.SelectedItem = null;
-------------MVVM
--------- Model :
class ItemViewModel : ViewModelBase
{
private string imageurl = string.Empty;
public string ImageUrl
{
get
{ return imageurl; }
set
{
if (imageurl == value)
{ return; }
imageurl = value;
isDirty = true;
RaisePropertyChanged("ImageUrl");
}
}
private decimal unit_price = 0;
public decimal Unit_Price
{
get
{ return unit_price; }
set
{
if (unit_price == value)
{ return; }
unit_price = value;
isDirty = true;
RaisePropertyChanged("Unit_Price");
}
}
}
---------- View Model
class ItemsViewModel : ViewModelBase
{
private ObservableCollection items;
public ObservableCollection Items
{
get
{
return items;
}
set
{
items = value;
RaisePropertyChanged("Items");
}
}
public ObservableCollection GetItems()
{
items = new ObservableCollection();
using (var db = new SQLite.SQLiteConnection(App.DBPath))
{
var query = db.Table().Where(c=> c.CompanyName == Company).OrderBy(c => c.No);
foreach (var _item in query)
{
var item = new ItemViewModel()
{
No = _item.No,
ImageUrl = "ms-appdata:///local/" + _item.PictureFilename,
Unit_Price = _item.Unit_Price,
Description = _item.Description
};
items.Add(item);
}
}
return items;
}
Try to bind ImageSource (not string)
Try to copy the Image folder in the Folder wherever you are using or Register the Every image in Register.resx and call the image by its name given in the Register

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

Pagination not working for a Lazy Loaded Data Table on First Loading

I am using JPA named queries for Loading a Lazy Loaded DataTable. and setting first and Max results as shown below.
Query query = entityManager.createNamedQuery("StudyplanCategory.findByStatusAndLimit");
int end=(start*pageNumber);
query.setParameter("status", status);
query.setParameter("start", start);
query.setParameter("end", end);
query.setMaxResults(end - start);
The load method is given below:
public List<StudyplanCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
List<StudyplanCategory> data = new ArrayList<StudyplanCategory>();
//System.out.println("Page First Value:"+first+"PageSize Value:"+pageSize);
datasource=categoryService.findDynaEditStudyPlan("NOT_USER_SPECIFIC",first,pageSize);
//filter
for(StudyplanCategory studyplanCategory : datasource) {
boolean match = true;
for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = filters.get(filterProperty).toLowerCase();
String fieldValue = String.valueOf(studyplanCategory.getClass().getDeclaredField(filterProperty).get(studyplanCategory)).toLowerCase();
//System.out.println("fieldValue............."+fieldValue);
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(Exception e) {
match = false;
System.out.println("The Exception occured at"+e);
}
}
if(match) {
data.add(studyplanCategory);
}
}
//sort
if(sortField != null) {
Collections.sort(data, new LazySorter(sortField, sortOrder));
}
//rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else {
return data;
}
}
But when the table is loaded Next Buttons are not active because I am loading only those data required to load the first page. How can I Solve this.
You need to fire another query which sets the total rowcount. Basically, in LazyDataModel#load():
public List<StudyplanCategory> load(...) {
setRowCount(studyplanCategoryService.count());
return studyplanCategoryService.list(...);
}
Unrelated to the concrete problem, you should actually be using Query#setFirstResult() to set the first record index.