I'm trying to upload images in Xamarin to Server via API.
.xaml
<Grid x:Name="pickimg" Grid.Row="0" Grid.Column="1" HorizontalOptions="End" VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<Image Margin="0">
<Image.Source>
<FontImageSource Color="#ddd" Size="22" FontFamily="MaterIcon" Glyph="{x:Static local:FontIconsClass.Camera}"/>
</Image.Source>
</Image>
</StackLayout>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="pickimg_Tapped" />
</Grid.GestureRecognizers>
</Grid>
<StackLayout HorizontalOptions="FillAndExpand">
<StackLayout x:Name="listImg" Orientation="Horizontal">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame HasShadow="False" Padding="0" IsClippedToBounds="True" CornerRadius="4">
<Image HeightRequest="70" WidthRequest="70" Aspect="AspectFill" Source="{Binding .}"/>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
.xaml.cs
This is how I display the list of selected photos:
async void pickimg_Tapped(System.Object sender, EventArgs e)
{
var pickResult = await MediaGallery.PickAsync(5, MediaFileType.Image);
if(pickResult?.Files == null)
{
return;
}
else
{
var imgList = new List<ImageSource>();
foreach (var img in pickResult?.Files)
{
var stream = await img.OpenReadAsync();
imgList.Add(ImageSource.FromStream(() => stream));
}
BindableLayout.SetItemsSource(listImg, imgList);
}
}
Everything seems fine. And I have 1 button to post the image to the Server:
private async void bt_addfeed_Clicked(object sender, EventArgs e)
{
var getResult = listImg;//How can I check and get the list of images in listImg?
if(getResult == null)
{
return;
}
else
{
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("", content);......
}
}
How can I check and get the list of images in listImg? Please solutions, Thanks
Update...
List<ImageSource> imgList = new List<ImageSource>();
async void pickimg_Tapped(System.Object sender, EventArgs e)
{
var pickResult = await MediaGallery.PickAsync(5, MediaFileType.Image);
if(pickResult?.Files == null)
{
return;
}
else
{
foreach (var img in pickResult?.Files)
{
var stream = await img.OpenReadAsync();
imgList.Add(ImageSource.FromStream(() => stream));
}
BindableLayout.SetItemsSource(listImg, imgList);
}
}
private async void bt_addfeed_Clicked(object sender, EventArgs e)
{
var getResult = imgList;
if(getResult == null)
{
return;
}
else
{
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("", content);......
}
}
How can getResult get .FileName and .OpenReadAsync()?
content.Add(new StreamContent(await getResult.OpenReadAsync()), "file", getResult.FileName);
you are declaring imgList as a local variable, so it only has scope inside the method where you declare it
var imgList = new List<ImageSource>();
instead, declare it as a class level variable so it will be accessible throughout the page
// do this inside the class body, but NOT within a specific method
List<ImageSource> imgList = new List<ImageSource>();
Related
I'm loading images async into my Listview according to this answer: Xamarin - Asynchronous data binding
I'd like to display a ActivityIndicator while the page is loading the data from the web, but cannot figure out how to bind the visibility it to the task, so that it disappears when the task is done loading..
I've created a isLoading bool variable in my ViewModel.
I tried it this way in my ViewModel, but It's not working:
isLoading = true;
GetImagesCommand = new Command(async () => await DoGetImagesCommand(pCode, gCode, gUrl));
isLoading = false;
I also tried setting it in the Task, but isLoading is always false..
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
{
isLoading = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
foreach (var image in images)
Galleries.Add(image);
isLoading = false;
}
my 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:vm="clr-namespace:GalShare.ViewModel"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:forms="clr-namespace:RedCorners.Forms;assembly=RedCorners.Forms"
mc:Ignorable="d"
x:Class="GalShare.Views.Gallery">
<ContentPage.Content>
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
<CollectionView ItemsSource="{Binding Galleries}" x:Name="MyCollection" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView Padding="1">
<forms:Frame2 CornerRadius="15"
HasShadow="True"
ShadowRadius="8"
Padding="0">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="2">
<ffimageloading:CachedImage x:Name="myImage" Source="{Binding ThumbUrl}" Aspect="AspectFit" CacheDuration="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" DownsampleToViewSize="False"></ffimageloading:CachedImage>
<Label x:Name="Picname" Text="{Binding ImageName}" IsVisible="{Binding showName}" VerticalOptions="StartAndExpand" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" ></Label>
</StackLayout>
</forms:Frame2>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
<StackLayout IsVisible="{Binding isLoading}" x:Name="LoadingLayout" Padding="12"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
<ActivityIndicator />
<Label Text="Loading gallery..." HorizontalOptions="Center" TextColor="Black"/>
</StackLayout>
</AbsoluteLayout>
</ContentPage.Content>
my ViewModel:
namespace GalShare.ViewModel
{
class GalleryViewModel
{
public string pCode { get; set; }
public string gCode { get; set; }
public string gUrl { get; set; }
public bool isLoading { get; set; }
public bool showname { get; set; }
public ObservableCollection<picdata> Galleries { get; } = new ObservableCollection<picdata>();
public ICommand GetImagesCommand { get; }
private GalleryService _galleryService;
public GalleryViewModel(string pCode, string gCode, string gUrl, string showName)
{
this.pCode = pCode;
this.gCode = gCode;
this.gUrl = gUrl;
_galleryService = new GalleryService();
GetImagesCommand = new Command(async () => DoGetImagesCommand(pCode, gCode, gUrl, showName));
}
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl, string showName)
{
isLoading = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl, showName);
foreach (var image in images)
Galleries.Add(image);
isLoading = false;
}
}
}
galleryservice:
class GalleryService
{
private HttpClient _httpClient;
public GalleryService()
{
_httpClient = new HttpClient();
}
public async Task<IEnumerable<picdata>> GetImageList(string pCode, string gCode, string gUrl, string showName)
{
var response = await _httpClient.GetAsync(gUrl).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// var json = response.Content.GetStringAsync().ConfigureAwait(false);
var deserialized = JsonConvert.DeserializeObject<JsonTxt>(json);
bool shownametemp;
if (showName == "1")
{
shownametemp = true;
}
else
{
shownametemp = false;
}
var images = new List<picdata>();
foreach (var img in deserialized.Files)
{
images.Add(new picdata()
{
ImageName = img.file,
BaseUrl = deserialized.Settings.Path.ToString(),
ThumbUrl = deserialized.Settings.Path.ToString() + "thumbs/" + img.file,
showname = shownametemp
}) ;
}
return images;
}
return new picdata[0]; // return empty set
}
}
You sould use ActivityIndicator like that
<ActivityIndicator AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All"
IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
Color="{StaticResource PrimaryColor}"
VerticalOptions="Center"
HorizontalOptions="Center" />
Use IsRunning property with IsBusy property
private bool _isBusy;
public bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
RaisePropertyChanged(() => IsBusy);
}
}
in viewmodel
class GalleryViewModel : ExtendedBindableObject
{
...
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
{
IsBusy = true;
var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
foreach (var image in images)
Galleries.Add(image);
IsBusy = false;
}
}
in another class
public abstract class ExtendedBindableObject : BindableObject
{
public void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
var name = GetMemberInfo(property).Name;
OnPropertyChanged(name);
}
private MemberInfo GetMemberInfo(Expression expression)
{
MemberExpression operand;
LambdaExpression lambdaExpression = (LambdaExpression)expression;
if (lambdaExpression.Body is UnaryExpression)
{
UnaryExpression body = (UnaryExpression)lambdaExpression.Body;
operand = (MemberExpression)body.Operand;
}
else
{
operand = (MemberExpression)lambdaExpression.Body;
}
return operand.Member;
}
}
I have a question here (I imagine it is for beginners: P).
I have a listview and a searchbar already working. I can make the right filter.
Then my question comes in, this listview has more than one column.
I can't think of a way to make 2 complementary filters.
For example:
Filter column 1 and then filter the result of that initial filter by column 2 (with another searchbar), that is, a filter on top of another filter.
My ListViewItem is like this with the filter:
C#
void InitList()
{
Items = new List<ListViewItem>
{
new ListViewItem { Name = "Guilherme", Bairro = "BOTAFOGO"},
new ListViewItem { Name = "João", Bairro = "FLAMENGO"},
new ListViewItem { Name = "Maria", Bairro = "CENTRO"}
}
}
void InitSearchBarBloco()
{
sb_search_bloco.TextChanged += (s, e) => FilterItem(sb_search_bloco.Text);
sb_search_bloco.SearchButtonPressed += (s, e) =>
FilterItem(sb_search_bloco.Text);
}
private void FilterItem(string filter)
{
exampleListView.BeginRefresh();
if (string.IsNullOrWhiteSpace(filter))
{
exampleListView.ItemsSource = Items;
}
else
{
exampleListView.ItemsSource = Items.Where(x => x.Name.ToLower().Contains(filter.ToLower()));
}
exampleListView.EndRefresh();
}
XAML
<SearchBar x:Name="sb_search_bloco" Placeholder="Nome..." />
<ListView x:Name="exampleListView" RowHeight="22" SelectedItem="{Binding Name}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<Grid>
<Label Text="{Binding Name}" LineBreakMode="TailTruncation" />
<Label Grid.Column="1" Text="{Binding Bairro}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
With this structure I can implement this ... "filtrate filter"?
thanks
I guess the below code should do fine for you. You just need to alter your linq code inside the FilterItem(string filter) method to achieve your requirement.
Note:
I have used OR condition inside the where clause to search if the enter text is available in both Name and Bairro. However, you can modify the condition as you require.
private void FilterItem(string filter)
{
exampleListView.BeginRefresh();
if (string.IsNullOrWhiteSpace(filter))
{
exampleListView.ItemsSource = Items;
}
else
{
//Alter the condition like below or based on requirement to achieve the desired result.
exampleListView.ItemsSource = Items.Where(x => x.Name.ToLower().Contains(filter.ToLower()) || x.Bairro.ToLower().Contains(filter.ToLower()));
}
exampleListView.EndRefresh();
}
I make a sample code for your referece.
xmal:
<StackLayout>
<StackLayout>
<SearchBar x:Name="sb_search_bloco" Placeholder="Nome..." TextChanged="sb_search_bloco_TextChanged"/>
<SearchBar x:Name="searchBar2" Margin="0,10" TextChanged="searchBar2_TextChanged" />
</StackLayout>
<ListView
x:Name="exampleListView"
RowHeight="22"
ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Label LineBreakMode="TailTruncation" Text="{Binding Name}" />
<Label Grid.Column="1" Text="{Binding Bairro}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
ListViewItem.cs
public class ListViewItem
{
public string Name { get; set; }
public string Bairro { get; set; }
}
MainPage.xml.cs
public partial class MainPage : ContentPage
{
public List<ListViewItem> Items { get; set; }
public MainPage()
{
InitializeComponent();
Items = new List<ListViewItem>
{
new ListViewItem { Name = "AAAA", Bairro = "BBCFS"},
new ListViewItem { Name = "ABBB", Bairro = "SSDCA"},
new ListViewItem { Name = "AAAA", Bairro = "AAAD"},
new ListViewItem { Name = "CCCC", Bairro = "SSS"},
new ListViewItem { Name = "DAAB", Bairro = "CCC"},
new ListViewItem { Name = "DDDC", Bairro = "QWDAS"}
};
this.BindingContext = this;
}
private void sb_search_bloco_TextChanged(object sender, TextChangedEventArgs e)
{
exampleListView.ItemsSource = FilterItem1(e.NewTextValue);
}
IEnumerable<ListViewItem> FilterItem1(string filter = null)
{
if (string.IsNullOrEmpty(filter))
return Items;
return Items.Where(p => p.Name.StartsWith(filter));
}
private void searchBar2_TextChanged(object sender, TextChangedEventArgs e)
{
exampleListView.ItemsSource = FilterItem2(e.NewTextValue);
}
IEnumerable<ListViewItem> FilterItem2(string filter = null)
{
if (string.IsNullOrEmpty(filter))
return Items;
return Items.Where(p => p.Bairro.StartsWith(filter));
}
}
This is my DisplayData.xaml:
<ContentPage.Content>
<StackLayout>
<ListView x:Name="RecordList"
ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
Margin="20, 10, 20, 0" >
<Label Text="{Binding Text}"
HorizontalOptions="StartAndExpand"
TextColor="WhiteSmoke"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Entry x:Name="TextEntry"
Placeholder="hehe"
IsVisible="False"/>
<Entry x:Name="IDEntry"
Placeholder="hehe"
IsVisible="False"/>
</StackLayout>
</ContentPage.Content>
This is my DisplayData.xaml.cs:
public partial class DisplayData : ContentPage
{
string _dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "myDatabase.db3");
SpeechRecTable _speech = new SpeechRecTable();
public DisplayData()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
var db = new SQLiteConnection(_dbPath);
RecordList.ItemsSource = db.Table<SpeechRecTable>().OrderBy(x => x.Text).ToList();
}
private void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
_speech = (SpeechRecTable)e.SelectedItem;
TextEntry.Text = _speech.Text;
IDEntry.Text = _speech.Id.ToString();
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PushAsync(new RecordContent(TextEntry.Text, IDEntry.Text));
});
}
}
When a listview Item is selected it looks like this on my RecordContent.xaml:
When I click my delete button it does not delete that record, this the code for delete:
private async void BtnDelete_Clicked(object sender, EventArgs e)
{
var db = new SQLiteConnection(_dbPath);
db.Table<SpeechRecTable>().Delete(x => x.Id == _speech.Id);
await Navigation.PopAsync();
}
even if I use:
db.Delete<SpeechRecTable>(Id);
instead of:
db.Table<SpeechRecTable>().Delete(x => x.Id == _speech.Id);
The Item will still not be deleted, and most of the tutorials that or guides that I have encountered has only one view page with the add,delete, and update button. I am trying to separate the delete and update button, my update button works just fine, but the delete is not working, it just immediately execute this: await Navigation.PopAsync(); and then nothing happens.
I have already solved my problem, by using this:
private void BtnDelete_Clicked(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(async () =>
{
var result = await this.DisplayAlert("Delete Item", "Are you sure that you want to DELETE this record?", "Yes", "No");
if (result)
{
var db = new SQLiteConnection(_dbPath);
_speech.Id = Convert.ToInt32(DataIdEntry.Text);
db.Table<SpeechRecTable>().Delete(x => x.Id == _speech.Id);
await Navigation.PopAsync();
}
else
{
}
});
}
Ok I am using Lockito from the app store andriod to mock my location and I am getting the first long and lat but its not updating as it should I am storing the location in a list
This function here locationObtained does not appear to be getting called more than once.
I am using a real device for testing and have granted pemission to location.
private async Task<int> StartGps()
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await DisplayAlert("Need location", "Gunna need that location", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
status = results[Permission.Location];
}
ILocation loc = DependencyService.Get<ILocation>();
loc.locationObtained += (object ss, ILocationEventArgs ee) =>
{
lat = ee.lat;
lng = ee.lng;
lbllat.Text = ee.lat.ToString();
lbllong.Text = ee.lng.ToString();
Position position = new Position(lat, lng);
postionsList.Add(position);
};
listPostions.ItemsSource = postionsList;
loc.ObtainMyLocation();
return 1;
}
In My Listview I have the following.
<ListView x:Name="listPostions" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Latitude}"
TextColor="#f35e20" />
<Label Text="{Binding Longitude}"
HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The problem is its not auto updating my app i have seti lockito to be the choosen app in developer options I have location on and can see the movement in Lockito fine but i cant see the orther cordinates from Lockito comming into my app.
This is my andriod function
public class GetMyLocation : Java.Lang.Object, ILocation, ILocationListener
{
public event EventHandler<ILocationEventArgs> locationObtained;
public void ObtainMyLocation()
{
LocationManager lm = (LocationManager)Forms.Context.GetSystemService(Context.LocationService);
lm.RequestLocationUpdates(LocationManager.NetworkProvider,0, 0, this);
}
public void OnLocationChanged(Location location)
{
if (location != null)
{
LocationEventArgs args = new LocationEventArgs();
args.lat = location.Latitude;
args.lng = location.Longitude;
locationObtained(this, args);
}
}
public void OnProviderDisabled(string provider)
{
}
public void OnProviderEnabled(string provider)
{
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
{
}
}
I'm trying to display the movie dates for movies than are going to screen today. I have been reading different threads the whole day, buy I can´t get the webRequest to work.
Basically I had working code with webClient, but I wanted the UI to be responsive so I decided to use httpWebRequest to keep the xml parsing off the UI thread.
public partial class MainPage : PhoneApplicationPage {
public MainPage() {
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
DoHttpWebRequest();
}
private void DoHttpWebRequest() {
string url = "http://www.cinamon.ee/rss/schedule/1001.xml";
var request = HttpWebRequest.Create(url);
var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
}
private void ResponseCallback(IAsyncResult result) {
var request = (HttpWebRequest)result.AsyncState;
var response = request.EndGetResponse(result);
using (var stream = response.GetResponseStream()) {
XDocument scheduleXml = XDocument.Load(stream);
var todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie() {
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
// Removing duplicate movies from list.
List<Movie> todayList = todayMovies.ToList();
IEnumerable<Movie> noDuplicates3 = todayList.Distinct(new MovieComparer());
// Adding to the UI
Dispatcher.BeginInvoke(() => {
todayBox.ItemsSource = noDuplicates.ToList();
});
}
}
}
Does anyone have an idea as to what is wrong by looking at this code?
Thank you in advance
EDIT. This is the link I based my solution on - http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/594e1422-3b69-4cd2-a09b-fb500d5eb1d8
EDIT2. My Mainpage.xaml
<StackPanel x:Name="TodayPanel" Grid.Row="1" Margin="10,5,10,10" Orientation="Horizontal" Height="580" Background="#90000000" >
<ListBox x:Name="todayBox">
<ListBox.ItemTemplate>
<DataTemplate>
<HyperlinkButton x:Name="hyperLinkButton" Style="{StaticResource HyperlinkButtonStyle1}" CommandParameter="{Binding MovieId}" Tap="hyperLinkButton_Tap">
<HyperlinkButton.Content>
<StackPanel Margin="10" Grid.Row="1" Orientation="Horizontal">
<Image Source="{Binding MoviePicture}" />
<StackPanel Margin="10" Grid.Row="1" Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Margin="10, 5, 10, 5" Width="200" FontFamily="Trebuchet MS" Foreground="Orange" VerticalAlignment="Top">
<Run Text="{Binding MovieName}"/>
<LineBreak></LineBreak>
</TextBlock>
<TextBlock TextWrapping="Wrap" Width="200" FontFamily="Trebuchet MS" Foreground="White" VerticalAlignment="Bottom">
<Run Text="Järgmine seanss: "/>
<LineBreak></LineBreak>
<Run Text="{Binding MovieSoonest}"/>
</TextBlock>
</StackPanel>
</StackPanel>
</HyperlinkButton.Content>
</HyperlinkButton>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
And my edited code behind.
private void DoHttpWebRequest() {
string url = "http://www.cinamon.ee/rss/schedule/1001.xml";
var request = HttpWebRequest.Create(url);
var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
}
private void ResponseCallback(IAsyncResult result) {
var request = (HttpWebRequest)result.AsyncState;
var response = request.EndGetResponse(result);
// Adding to the UI
Dispatcher.BeginInvoke(() => {
IEnumerable<Movie> todayMovies;
using (var stream = response.GetResponseStream()) {
XDocument scheduleXml = XDocument.Load(stream);
todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie() {
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
}
var todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates = movieList.Distinct(new MovieComparer());
todayBox.ItemsSource = todayList.ToList();
});
I tried out your code and getting UnauthorizedAccessException. By changing Dispactcher.Begininvoke delegate's scope it works as follow:
private void ResponseCallback(IAsyncResult result){
var request = (HttpWebRequest) result.AsyncState;
var response = request.EndGetResponse(result);
// Adding to the UI
Dispatcher.BeginInvoke(() =>
{
IEnumerable<Movie> todayMovies;
using (var stream = response.GetResponseStream())
{
XDocument scheduleXml = XDocument.Load(stream);
todayMovies =
from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) >
0
select new Movie()
{
MoviePicture =
new BitmapImage(
new Uri((string) query.Element("images").Element("imageType2").Value,
UriKind.RelativeOrAbsolute)),
MovieName = (string) query.Element("title"),
MovieId = (string) query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
}
// Removing duplicate movies from list.
var todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates3 = todayList.Distinct(new MovieComparer());
todayBox.ItemsSource = todayList.ToList();
});
}
However you may use RestSharp library (you may find it in Nuget) in order to make it easier. Check following code:
public void RestSample(){
var client = new RestClient
{
BaseUrl = "http://www.cinamon.ee/"
};
var request = new RestRequest
{
Resource = "rss/schedule/1001.xml"
};
client.ExecuteAsync(request, (a) =>
{
if (a.StatusCode == HttpStatusCode.OK)
{
var scheduleXml = XDocument.Parse(a.Content);
var todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie()
{
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
// Removing duplicate movies from list.
List<Movie> todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates = todayList.Distinct(new MovieComparer());
// Adding to the UI
Dispatcher.BeginInvoke(() =>
{
todayBox.ItemsSource = todayList.ToList();
});
}
else
{
//error
}
});
}
Try it out and let us know...
EDITED: xaml.cs datatemplate:
<StackPanel x:Name="TodayPanel" Grid.Row="1" Margin="10,5,0,10" Orientation="Horizontal" Height="580" Background="#90000000" >
<ListBox x:Name="todayBox" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10" Orientation="Horizontal">
<Image Source="{Binding MoviePicture, FallbackValue=http://www.cinamon.ee/visinternetticketing/images/movies/NowShowingComingSoon/HungerGames.jpg}" />
<StackPanel Margin="10" Grid.Row="1" Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Margin="10, 5, 10, 5" FontFamily="Trebuchet MS" Foreground="Orange" VerticalAlignment="Top" Text="{Binding MovieName}"/>
<TextBlock TextWrapping="Wrap" FontFamily="Trebuchet MS" Foreground="White" VerticalAlignment="Bottom" Text="{Binding MovieSoonest}"/>
</StackPanel>
<HyperlinkButton x:Name="hyperLinkButton" CommandParameter="{Binding MovieId}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
RECALL Change MovePicture Property from BitmapImage to string.