An error occurs when uploading additional galleries in MAUI(C#) - c#

When uploading images in the gallery, the first time is normal, but an error occurs when additional images are uploaded.
Could you please confirm what could be the problem?
Error string :
System.ObjectDisposedException: 'Cannot access a closed Stream.'
The source below is my source uploaded on Github.
My source in Github
This is My Viewmodel variable.
private IEnumerable<PickImages> selectedItems;
public IEnumerable<PickImages> SelectedItems
{
get
{
return selectedItems;
}
set
{
SetProperty(ref selectedItems, value);
}
}
And This is My Model Class
public class PickImages
{
public ImageSource CombineDeleteMarkImage { get; set; }
public string MainImageYN { get; set; }
}
And I set My variable(selectedItems) Like this in viewModel
void Pick(View view, params MediaFileType[] types)
{
try
{
Task.Run(async () =>
{
CancellationTokenSource cts = null;
try
{
//DisposeItems();
cts = new CancellationTokenSource(
TimeSpan.FromMilliseconds(5000000));
var result = await MediaGallery.PickAsync(
new MediaPickRequest(SelectionLimit, types)
{
Title = $"Select {SelectionLimit} photos",
PresentationSourceBounds = view?.GetAbsoluteBounds(40),
UseCreateChooser = UseCreateChooser
},
cts.Token);
List<Image> liImageSource= new List<Image>();
List<PickImages> list = new List<PickImages>();
if (SelectedItems != null)
list = SelectedItems.ToList();
foreach (var item in await SetImage(result))
{
if (list.Count > 10)
{
return;
}
Image image = ImageHelper.ImageThumnailMaker(item);
bool blcheckMainimg = false;
foreach (var s_item in list)
{
if (s_item.MainImageYN.Equals("Y"))
{
blcheckMainimg = true;
break;
}
}
if (blcheckMainimg)
{
list.Add(new PickImages { CombineDeleteMarkImage = image.Source, MainImageYN = "N" });
}
else
{
//Image mImage = ImageHelper.CombineWithMain(item);
list.Add(new PickImages { CombineDeleteMarkImage = image.Source, MainImageYN = "Y" });
}
}
SelectedItems = list;
}
catch (Exception ex)
{
OperationInfo = ex.Message;
}
finally
{
cts?.Dispose();
}
});
}
catch (Exception)
{
throw;
}
}
When registering an image for the first time, it is normal, but when registering an additional image from the original gallery image, a Stream Error occurs.
And this is my xaml.
<BindableLayout.ItemTemplate>
<DataTemplate>
<ContentView Padding="0,8">
<Grid>
<AbsoluteLayout>
<Image Source="{Binding SelectedItems.CombineDeleteMarkImage}"
WidthRequest="80"
HeightRequest="80"
VerticalOptions="Center"
HorizontalOptions="Center" />
<myc:MyBoxView
AbsoluteLayout.LayoutBounds="1,0,0.3,0.3"
AbsoluteLayout.LayoutFlags="All">
<BoxView.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding BoxViewTapCommand}"
/>
</BoxView.GestureRecognizers>
</myc:MyBoxView>
</AbsoluteLayout>
</Grid>
<ContentView.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ImageTapGestureCommand}"/>
</ContentView.GestureRecognizers>
</ContentView>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
What am i missing?

Related

Xamarin Forms Binding Base64 image to CarouselView Image Source

I have the following code in my XAML (Visual Studio 2019 Community Edition)
<CarouselView x:Name="TheCarousel" PeekAreaInsets="50" Loop="False" >
<CarouselView.EmptyView>
<Label Text="Search Results"/>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="10"
HeightRequest="20"
VerticalOptions="Start" >
<StackLayout>
<Image x:Name="ProductImage" Source="{Binding Image}"/>
<Label x:Name="ProduceDescription" Text="{Binding ProductDescription}"/>
<Label x:Name="AmountInStock" Text="{Binding AmountInStock}"/>
<Label x:Name="ProductPrice" Text="{Binding productprice}"/>
</StackLayout>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
And the following code in my model
private string imageBase64;
public string productphoto1
{
get { return imageBase64; }
set
{
try
{
imageBase64 = value;
if (imageBase64 != null)
{
if (imageBase64.Trim() != "")
{
//imageBase64 = "data:image/png;base64," + imageBase64;
var byteArray = Convert.FromBase64String(imageBase64);
if (byteArray != null)
{
//Stream stream = new MemoryStream(byteArray);
//Image = ImageSource.FromStream(() => stream);
Image = Xamarin.Forms.ImageSource.FromStream(
() => new MemoryStream(Convert.FromBase64String(imageBase64)));
}
}
}
}
catch (Exception ex)
{
string strErrMessage = ex.Message + " " + ex.Source;
}
}
}
private Xamarin.Forms.ImageSource image;
public Xamarin.Forms.ImageSource Image
{
get { return image; }
set
{
image = value;
}
}
The code is returning values and returns the base64 image and seems to convert it properly. However, the images are not displaying in the CarouselView. Is there something that I am missing?
I have tried setting "Binding Image" to "Binding Path=Image", but the images are still not loading.
Thanks in advance.
//James
I couldn't see other codes of your app, but based on your code,I created a demo which works on my android emulator.
You can refer to the following code:
1.create an item and implement interface INotifyPropertyChanged. Then once changing the value of field ImageBase64, the UI will update automatically.
public class Item: INotifyPropertyChanged
{
private string imageBase64;
public string ImageBase64
{
get { return imageBase64; }
set
{
SetProperty(ref imageBase64, value);
try
{
// imageBase64 = value;
SetProperty(ref imageBase64, value);
if (imageBase64 != null)
{
if (imageBase64.Trim() != "")
{
//imageBase64 = "data:image/png;base64," + imageBase64;
var byteArray = Convert.FromBase64String(imageBase64);
if (byteArray != null)
{
Image = Xamarin.Forms.ImageSource.FromStream(
() => new MemoryStream(Convert.FromBase64String(imageBase64)));
}
}
}
}
catch (Exception ex)
{
string strErrMessage = ex.Message + " " + ex.Source;
}
}
}
private Xamarin.Forms.ImageSource image;
public Xamarin.Forms.ImageSource Image
{
get => image;
set => SetProperty(ref image, value);
}
public double productprice { get; set; }
public int AmountInStock { get; set; }
public string ProductDescription { get; set; }
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
2.create viewmodel MyViewModel
public class MyViewModel
{
string base64Image = "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";
string base64Image2 = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=";
public ObservableCollection<Item> Items { get; set; }
public ICommand ResetImage => new Command(reSetImage);
private void reSetImage(object obj)
{
Items[1].ImageBase64 = base64Image2;
}
public MyViewModel() {
byte[] Base64Stream = Convert.FromBase64String(base64Image);
Items = new ObservableCollection<Item>();
Items.Add(new Item { AmountInStock = 900, productprice = 10.0,ProductDescription = " ProductDescription1" , ImageBase64 = base64Image });
Items.Add(new Item { AmountInStock = 600, productprice = 19.0, ProductDescription = " ProductDescription2", ImageBase64 = base64Image });
Items.Add(new Item { AmountInStock = 890, productprice = 68.0, ProductDescription = " ProductDescription3", ImageBase64 = base64Image });
}
}
3.TestPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:formapp0111="clr-namespace:FormApp0111"
x:Class="FormApp0111.TestPage1">
<ContentPage.BindingContext>
<formapp0111:MyViewModel></formapp0111:MyViewModel>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Button Text="reset" Command="{Binding ResetImage}" />
<CarouselView x:Name="TheCarousel" PeekAreaInsets="50" Loop="False" ItemsSource="{Binding Items}" >
<CarouselView.EmptyView>
<Label Text="Search Results"/>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
<DataTemplate>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="10"
HeightRequest="20"
VerticalOptions="Start" >
<StackLayout>
<Image x:Name="ProductImage" Source="{Binding Image}"/>
<Label x:Name="ProduceDescription" Text="{Binding ProductDescription}"/>
<Label x:Name="AmountInStock" Text="{Binding AmountInStock}"/>
<Label x:Name="ProductPrice" Text="{Binding productprice}"/>
</StackLayout>
</Frame>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Note:
1.In class Item.cs, I replaced productphoto1 with ImageBase64.
private string imageBase64;
public string ImageBase64{// other code}
2.I also added a Button to reset the base64 image.
public ICommand ResetImage => new Command(reSetImage);

Xamarin Forms Stop loading data in CollectionView

I have a problem. I created a CollectionView that uses a custom ViewModel. In that ViewModel I do a webcall to my webpage to get 20 filenames of images. After I got the result I do foreach filename a call to get the ImageSource of that filename. Now I created a Load data incrementally code to load the CollectionView data in bundles of 20. Here is my xaml:
<ContentPage.Content>
<StackLayout HorizontalOptions="Fill" Padding="15">
<Frame IsClippedToBounds="True" HeightRequest="45" CornerRadius="5" Padding="0" BackgroundColor="Transparent">
<Entry Placeholder="Search" ReturnType="Done" PlaceholderColor="Gray" x:Name="txtSearch" Margin="5,0,0,0" TextColor="White" />
</Frame>
<CollectionView ItemsSource="{Binding sourceList}" RemainingItemsThreshold="6"
RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ff:CachedImage
Source="{Binding Source}"
VerticalOptions="Center"
HorizontalOptions="Center"
WidthRequest="{Binding WidthHeight}"
HeightRequest="{Binding WidthHeight}">
<ff:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="imgTemplate_Clicked" />
</ff:CachedImage.GestureRecognizers>
</ff:CachedImage>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage.Content>
Here is the page constructor:
public TemplateList()
{
InitializeComponent();
TemplateListViewModel vm = new TemplateListViewModel();
BindingContext = vm;
}
Here is the ViewModel:
public class TemplateListViewModel
{
public ICommand LoadTemplates => new Command(LoadTemplateList);
public int CurrentTemplateCountReceived;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public double MemeWidthHeight { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
MemeWidthHeight = (ScaledWidth / 2);
loadingTemplates += onLoadingTemplates;
LoadTemplateList();
}
private event EventHandler loadingTemplates = delegate { };
private void LoadTemplateList()
{
loadingTemplates(this, EventArgs.Empty);
}
private async void onLoadingTemplates(object sender, EventArgs args)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight= MemeWidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
}
Now App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived); just returns me a list with filenames, but the problem is that it keeps doing webcalls when I got nothing to receive anymore. On my server I have 38 images, so after 2 webcalls the app got everything. After that the result that the app receives from the webcall is "Nothing".
So my question is:
How can I stop doing the webcalls when I am at the bottom of my CollectionView?
bool moreData = true;
private async void onLoadingTemplates(object sender, EventArgs args)
{
if (!moreData) return;
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList is null or templateList.Count == 0) {
moreData = false;
return;
}
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight= MemeWidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}

Capture photo in xamarin forms

I want to take multiple photos and it is shown in a list, but I must use the mvvm structure if I put this code in the CS of the XAML it works but I cannot use it that way ...
The view model works and everything but does not show the image on the screen
What can be ??
You can tell me that I am doing wrong he tried everything but he does not show me the image.
Reference XAML (view) SEE MODEL and MODEL
public class CapturePhotoViewModel : BaseViewModel
{
ObservableCollection Photos = new ObservableCollection();
public ICommand CapturePhotoCommand => new Command(async (s) => await CaptureFoto());
private async Task CaptureFoto()
{
var IniciandoEvento = await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsPickPhotoSupported || !CrossMedia.IsSupported || !IniciandoEvento)
{
await DialogService.DisplayAlertAsync("No se puede Acceder a la camara", "¡Error!", "Aceptar");
return;
}
var newPhoto = Guid.NewGuid();
using (var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions()
{
Name = newPhoto.ToString(),
SaveToAlbum = true,
DefaultCamera = CameraDevice.Rear,
Directory = "Demo",
CustomPhotoSize = 50
}))
{
if (string.IsNullOrWhiteSpace(photo?.Path))
{
return;
}
var newphotomedia = new MediaModel()
{
MediaID = newPhoto,
Path = photo.Path,
LocalDateTime = DateTime.Now
};
Photos = new ObservableCollection<MediaModel>();
Photos.Add(newphotomedia);
}
}
}
THIS IS MY XAML CODE which goes the list of image that is captured, but I do not know what I am doing wrong and does not show me the image
<Button Text="Tomar Foto" x:Name="photobutton" Command="{Binding CapturePhotoCommand}"/>
<ListView x:Name="ListPhotos" ItemsSource="{Binding Photos.Source}" RowHeight="400"
HeightRequest="300">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Frame OutlineColor="LightGray" HasShadow="true" Margin="4" WidthRequest="200" HeightRequest="250">
<Frame.Content>
<StackLayout>
<Image Source="{Binding Source}" VerticalOptions="StartAndExpand" HeightRequest="280"/>
<Button Text="Delete" />
</StackLayout>
</Frame.Content>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Y Este es mi model
public class MediaModel
{
public Guid MediaID { get; set; }
public string Path { get; set; }
public DateTime LocalDateTime { get; set; }
private FileImageSource source = null;
public FileImageSource Source => source ?? (source = new FileImageSource() { File = Path });
}
first, get rid of this line
Photos = new ObservableCollection<MediaModel>();
then fix your ItemsSource binding
<ListView x:Name="ListPhotos" ItemsSource="{Binding Photos}" RowHeight="400"
then fix your Image binding
<Image Source="{Binding Path}" VerticalOptions="StartAndExpand" HeightRequest="280"/>

use dataBinding to put images into a ListViewItem according to a web Service values

I have a listview in wich each ListViewItem has a list of default images, those images will be replaced by other images if the value recovered from a web service is different from 0
this is the json data:
{
success: 1,
total: 2,
locals: [
{
id_local: "82",
fav: 0,
aime: 0,
aimepas: 0,
},
{
id_local: "83",
fav: 1,
aime: 1,
aimepas: 0,
}
]
}
I tried this code:
ObservableCollection<Item> Locals = new ObservableCollection<Item>();
public async void getListePerSearch()
{
UriS = "URL";
var http = new HttpClient();
http.MaxResponseContentBufferSize = Int32.MaxValue;
var response = await http.GetStringAsync(UriS);
var rootObject1 = JsonConvert.DeserializeObject<NvBarberry.Models.RootObject>(response);
listme.ItemsSource = rootObject1.locals;
foreach (var item in listme.Items.Cast<Locals>())
{
if (item.fav == 1)
{
btnStar.Background = new SolidColorBrush(Colors.Yellow); //yellow
//Debug.Write("fav=1");
}
else
{
btnStar.Background = new SolidColorBrush(Colors.Gray);//Gray
//Debug.Write("fav=0");
}
if (item.aime == 1)
{
coeur.Source = new BitmapImage(new Uri("ms-appx:///images/11.png", UriKind.Absolute));
//Debug.Write("aime=1");
}
else
{
coeur.Source = new BitmapImage(new Uri("ms-appx:///images/1.png", UriKind.Absolute));
//Debug.Write("aime=0");
}
if (item.aimepas == 1)
{
deslikeimage.Source = new BitmapImage(new Uri("ms-appx:///images/22.png", UriKind.Absolute));
//Debug.Write("aimepas=1");
}
else
{
deslikeimage.Source = new BitmapImage(new Uri("ms-appx:///images/2.png", UriKind.Absolute));
//Debug.Write("aimepas=0");
}
}
and this is Locals.cs:
public class Locals
{
public int fav { get; set; }
public int aime { get; set; }
public int aimepas { get; set; }
}
and this is the xaml file:
<ListView x:Name="listme">
<ListView.ItemTemplate >
<DataTemplate >
<Grid>
...
<Button Background="Gray" x:Name="btnStar"/>
<Button>
<Image Source="images/1.png" x:Name="coeur"/>
</Button>
<Button>
<Image Source="images/2.png" x:Name="deslikeimage"/>
</Button>
</Grid>
</DataTemplate >
</ListView.ItemTemplate >
</ListView >
so my question is,how can I use DataBinding in my case
thanks for help
Your class Item must implement INotifyPropertyChanged to notify to the view when some of your properties changed after that you need to set your ObservableCollection Locals as ItemsSource in your List control.
Here is the doc.
https://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.data.inotifypropertychanged.propertychanged.aspx
You need to understand what is Binding How to use it.
http://blogs.msdn.com/b/jerrynixon/archive/2012/10/12/xaml-binding-basics-101.aspx
Here is an example:
public class Employee : INotifyPropertyChanged
{
private string myUrl;
private string myUrl2;
public string MyUrl
{
get { return myUrl; }
set
{
_name = value;
RaisePropertyChanged("MyUrl");
}
}
public string MyUrl2
{
get { return myUrl2; }
set
{
_organization = value;
RaisePropertyChanged("MyUrl2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
Now in your foreach:
foreach (var item in MyOriginalCollection)
{
your logic here...
Locals.Add(Item);
}
Finally you need to set your Locals Collection to your ListControl.
ObservableCollection notifies to the view when some object is added or removed.
Here is the documentation
https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx
In Xaml
you need to personalize your ItemTemplate of your ListControl
<ListView x:Name="myList"
>
<ListView.ItemTemplate>
<DataTemplate>
<Button>
<Image Source="{Binding MyUrl}" x:Name="coeur"/>
</Button>
<Button>
<Image Source="{Binding MyUrl2}" x:Name="coeur"/>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I hope this information and example would be useful for you.
I know there are many concepts to learn.
Here a final example showing how to use Binding Approach
http://10rem.net/blog/2012/03/27/tip-binding-an-image-elements-source-property-to-a-uri-in-winrt-xaml

How to use FileUpload in Telerik RadDataForm in MVVM WPF?

I am developing a WPF application in MVVM pattern using caliburn.micro. I am stuck when I need to use a local path of my computer using fileupload or openfiledialog. I need to insert the path in the database. Here is the xaml:
<Grid Margin="20" Height="Auto" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="50*"></RowDefinition>
<RowDefinition Height="50*"></RowDefinition>
</Grid.RowDefinitions>
<Telerik:RadGridView x:Name="RadGridView1" GroupRenderMode="Flat"
ItemsSource="{Binding ModelList}"
ColumnWidth="*"
CanUserFreezeColumns="False"
RowIndicatorVisibility="Collapsed">
</Telerik:RadGridView>
<Telerik:RadDataForm Grid.Row="1"
x:Name="myRadDataForm"
ItemsSource="{Binding ModelList}"
Header="Model Details"
Margin="0,5,0,0" cal:Message.Attach="[Event DeletingItem] = [Action onDeleted()]">
</Telerik:RadDataForm>
</Grid>
I am using an ICollectionView as a datasource in viewmodel. Maybe I need to use a datatemplate in the dataform, but I don't know how to do that. Please let me know if you need any other info.
Code for ViewModel:
[Export(typeof(AddModelsViewModel))]
public class AddModelsViewModel : PropertyChangedBase
{
private Model _selectmodel;
List<Model> ModelsList = new List<Model>();
Model model = new Model();
private ICollectionView models = null;
public ICollectionView Models
{
get
{
if (this.models == null)
{
ObservableCollection<Model> allModels = new ObservableCollection<Model>();
ModelsList = model.GetAllModels();
foreach (Model m in ModelsList)
{
allModels.Add(m);
}
this.models = new QueryableCollectionView(allModels);
}
return this.models;
}
}
// Model model = new Model();
private List<Model> _ModelListAll;
// private ClsRole _selectedRole;
public Model selectedModel
{
get { return _selectmodel; }
set
{
_selectmodel = value;
NotifyOfPropertyChange(() => selectedModel);
}
}
public List<Model> ModelListAll
{
get { return _ModelListAll; }
set
{
_ModelListAll = value;
NotifyOfPropertyChange(() => ModelListAll);
}
}
public void onDeleted()
{
try
{
model.Delete(selectedModel);
}
catch (Exception ex)
{
Logger.GetInstance().Log(ex);
}
}
public void OnRoleViewLoad()
{
ModelListAll = model.GetAllModels();
if (ModelListAll.Count > 0)
{
selectedModel = ModelListAll[0];
}
}
private ICollectionView modelList = null;
public ICollectionView ModelList
{
get
{
if (this.modelList == null)
{
ObservableCollection<Model> Allmodel = new ObservableCollection<Model>();
ModelListAll = model.GetAllModels();
foreach (Model role in ModelListAll)
{
Allmodel.Add(role);
}
this.modelList = new QueryableCollectionView(Allmodel);
}
return this.modelList;
}
set
{
ModelList = value;
NotifyOfPropertyChange(() => ModelList);
}
}
public void OnRadGridView1SelectonChanged(Model modelClicked)
{
selectedModel = modelClicked;
}
}

Categories