XAML databind with conditions - c#

In a project for windows phone 8 , i have a List<> of objects of this type.
public class Media
{
public string idNews { get; set; }
public string video_url { get; set; }
public string idMenu { get; set; }
public string image { get; set; }
public string video_image { get; set; }
public string url { get; set; }
}
i then bind that list to a XAML
MediaScroll.DataContext = media.listaMedia;
and in my XAML i have
<ScrollViewer Name="MediaScroll" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" Background="{x:Null}" VerticalAlignment="Top" >
<ItemsControl Name="ItControl" ItemTemplate="{StaticResource ItemTemplate2}" ItemsPanel="{StaticResource ItemsPanelTemplate1}" ItemsSource="{Binding}" />
</ScrollViewer>
and
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="ItemTemplate2">
<StackPanel Width="480">
<Image Name="overlay" Source="/Assets/play#2x.png" Width="75" Canvas.ZIndex="10" Margin="203,85,202,0" />
<Image Tag="{Binding id}" Source="{Binding image}" Stretch="Fill" VerticalAlignment="Top" Margin="0,-160,0,0" Tap="Image_Tap" />
</StackPanel>
</DataTemplate>
my question is , how can i bind either image or video_image depending on witch on ins't empty, also , how can i make " Image Name="overlay" " only display if the other image is bound with a video_image

Inside your StackPanel, create only one Image control that has the Source set up with a Binding image.
Create a Converter and attach that to your Binding to programatically return either your play#2x.png as an ImageSource or your image.

Related

WPF C# add text and image to ComboBox during runtime

Basically, when a user clicks a button I would like to add a list of the names of the currently running applications with their icon next to them within a ComboBox. I know how to get my list of applications and my icons but am unsure how to link everything together. My XAML for the ComboBox currently looks like the following:
<ComboBox x:Name="dial1AppSelection" Grid.Column="3" Grid.Row="4" MinHeight="25" Height ="25" MaxHeight="35" MinWidth="120" Margin="4,0,0,0" SelectionChanged="dial1AppSelection_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="20" Source="???" />
<TextBlock ><Run Text="???" /></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Add to your combobox
ItemsSource="{Binding YourCollection}"
Create class for your objects:
public class MyProcess
{
public ImageSource Image { get; set; }
public string Text { get; set; }
}
Add such code to your MainWindow.xaml.cs
public ObservableCollection<MyProcess> YourCollection { get; set; }
public MainWindow()
{
InitializeComponent();
YourCollection = new ObservableCollection<MyProcess>();
YourCollection.Add(new MyProcess() { Image ="image1", Text = "txt1"});
DataContext = this;
}
Insert fields names to your xaml code:
Source="{Binding Path=Image}"
Text="{Binding Path=Text}"

Data binding Pivot control while data binding within each Pivot items data template

So I have an ``ObservableCollection which I'm binding to a Pivot control. This ObservableCollection has a child that is also an ObservableCollection and I'm trying to bind a GridView in each Pivotitem's body.
I've tested my code-behind to ensure the collections are populated i.e.
// Level 1 ObservableCollection
foreach (var dchallenge in ChallengesList)
{
// Level 2 ObservableCollection
Debug.WriteLine(dchallenge.Name);
foreach (var dactivity in dchallenge.Activities)
{
Debug.WriteLine(dactivity.Name);
}
}
And its output is as expected.
For reference, my model is as follows:
public class Challenge
{
public string Type { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Slug { get; set; }
public string Image { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ObservableCollection<Activity> Activities { get; set; }
public class Activity
{
public string Name { get; set; }
public string Description { get; set; }
public long Hash { get; set; }
}
}
And finally, my view:
<Pivot x:Name="Items" ItemsSource="{x:Bind ChallengesList, Mode=OneWay}" Margin="20,417,0,0">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="data:Challenge">
<TextBlock Text="{Binding Name, Mode=OneWay}" FontWeight="Normal" FontSize="16"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate x:DataType="data:Challenge">
<StackPanel Margin="0,20,0,0" HorizontalAlignment="Left">
<TextBlock Text="{Binding Description, Mode=OneWay}" MaxWidth="300" TextWrapping="WrapWholeWords"/>
<TextBlock Text="Activities" FontWeight="Medium" MaxWidth="300" Margin="0,20,0,0"/>
<!--<GridView DataContext="{Binding}" ItemsSource="{x:Bind Activities}" SelectionMode="None"
IsItemClickEnabled="False" IsSwipeEnabled="False" CanDragItems="False"
HorizontalAlignment="Left" Margin="0,70,0,0" VerticalAlignment="Top" Width="300">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Challenge">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock FontSize="16" Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>-->
</StackPanel>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
A GridView may not be the control that I finally settle on, but if I know how to bind it then I should be able to use that knowledge with another control.
Intellisense helps a lot in determining which properties are available, but Activities isn't one. I only get strings such as Name and Description which work correctly (first two TextBlock).
The only problem I see is that you are using the wrong DataType in the inner GridView. The type in Activities collection is Challenge.Activity, which is a nested class and nested classes are denoted by plus sign (+) in XAML, so data:Challenge+Activity:
<GridView DataContext="{Binding}" ItemsSource="{x:Bind Activities}" SelectionMode="None"
IsItemClickEnabled="False" IsSwipeEnabled="False" CanDragItems="False"
HorizontalAlignment="Left" Margin="0,70,0,0" VerticalAlignment="Top" Width="300">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Challenge+Activity">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock FontSize="16" Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
VS may still throw some warnings but those will disappear after successful compilation.

Windows Phone Longlistselector ItemsSource Performance

I'm working on an app for Windows Phone (Silverlight WP 8.0) with a custom UserControl containing three LongListSelectors. This UserControl sits inside of a Panorama. When an item is selected from the first list, the user control changes visual states and animates the second list in, and the same for the third. The problem I'm encountering is the long load time between changing the ItemsSource of the list (either explicitly or through binding) and the actual rendering of the items. With a list of about 20 items, the time is at least 500ms, sometimes over 1 second. This seems unreasonable. Here's the XAML I'm working with:
MainPage.xaml:
<phone:Panorama Template="{StaticResource TunrPanorama}">
<!--Panorama item one-->
<phone:PanoramaItem Background="White" Style="{StaticResource MusicPanoramaItemStyle}">
<tunr:LibraryControl DataContext="{Binding}" TrackSelected="LibraryControl_TrackSelected" />
</phone:PanoramaItem>
LibraryControl.xaml:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel x:Name="stackPanel" Grid.Row="0" Orientation="Vertical" Height="108">
<!-- Some headers here -->
</StackPanel>
<Grid Grid.Row="1" Margin="12,0,0,0">
<!-- List number 1 -->
<phone:LongListSelector Grid.Row="0" Grid.Column="0" x:Name="music_artists" VerticalAlignment="Stretch" ItemsSource="{Binding ArtistList}" SelectionChanged="music_artists_SelectionChanged" RenderTransformOrigin="0.5,0.5">
<phone:LongListSelector.RenderTransform>
<CompositeTransform/>
</phone:LongListSelector.RenderTransform>
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<ListBoxItem Margin="0,6,0,6">
<StackPanel>
<TextBlock Text="{Binding}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeLarge}" Foreground="Black"/>
</StackPanel>
</ListBoxItem>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
<!-- List number 2 -->
<phone:LongListSelector Grid.Row="0" Grid.Column="0" x:Name="music_albums" LayoutMode="Grid" GridCellSize="190,190" SelectionChanged="music_albums_SelectionChanged" RenderTransformOrigin="0.5,0.5">
<phone:LongListSelector.RenderTransform>
<CompositeTransform/>
</phone:LongListSelector.RenderTransform>
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<ListBoxItem Margin="6,6,6,6">
<Grid>
<Border Width="178" Height="178" Background="#FF838383" />
</Grid>
</ListBoxItem>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
<!-- List number 3 -->
<phone:LongListSelector Grid.Row="0" Grid.Column="0" x:Name="music_tracks" SelectionChanged="music_tracks_SelectionChanged">
<phone:LongListSelector.RenderTransform>
<CompositeTransform/>
</phone:LongListSelector.RenderTransform>
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<ListBoxItem Margin="0,6,0,6">
<StackPanel>
<TextBlock Text="{Binding Title}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeLarge}" Foreground="Black"/>
</StackPanel>
</ListBoxItem>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
</Grid>
Here's the code that populates the list:
(DataContext as LibraryViewModel).SelectAlbum(album).ContinueWith((songs) => {
Dispatcher.BeginInvoke(() =>
{
music_tracks.ItemsSource = songs.Result;
VisualStateManager.GoToState(this, "Tracks", true);
});
});
All the SelectAlbum method above does now is return a list of newly created Song instances - no other processing is done, so this should not be any sort of performance hog. But still there is a huge delay in rendering.
I've turned off transitions in my visual state changes to no avail; the list still takes too long to load. I've also experimented by creating a fresh new project with a LLS inside of a Panorama, populating it with a button press to see the delay. It's almost instant. The only difference between that and my project seems to be the UserControl I've nested these lists inside of - can that be the cause of this bad performance?
Any suggestions are very much appreciated!
For good measure, here's the class of the item I'm rendering:
public class SongModel
{
public Guid SongID { get; set; }
//public string SongFingerPrint { get; set; }
public Guid OwnerId { get; set; }
public string SongMD5 { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
public string Album { get; set; }
public int TrackNumber { get; set; }
public int DiscNumber { get; set; }
public int Year { get; set; }
public string Genre { get; set; }
public double Length { get; set; }
}
Why do you use LongListSelector? Have you seen this ?
I mean, if an amount of the items is fixed and you do not use grouping, should be enough to use ListBox. Did you try that?

ListBox not databinding

My ListBox control is working fine, except that the data to be bound is not displaying.
My XAML:
<ListBox x:Name="listFileNames" SelectionMode="Single" Margin="10">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Margin="5" Source="{Binding Path=Image}" Stretch="Fill" Width="50" Height="50"></Image>
<StackPanel Grid.Column="1" Margin="5">
<TextBlock Text="{Binding Path=FileName}" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding Path=State}"></TextBlock>
<TextBlock Text="This text shows..."></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My code:
public struct StyleDocumentFile
{
public string Image;
public string FileName;
public string State;
}
// ......
StyleDocumentFile sdf = new StyleDocumentFile()
{
Image = "/Images/Loading.png",
FileName = "abc",
State = "Extracting Data...",
};
this.listFileNames.Items.Add(sdf);
Change fields to Property. After this, all works fine.
public struct StyleDocumentFile
{
public string Image { get; set; }
public string FileName { get; set; }
public string State { get; set; }
}
You should set ItemsSource in ListBox definition like ItemsSource="{Binding Model.Items}". In addition you must call RaisePropertyChanged in setter of model properties.

Windows Phone Bind Listbox With a Listbbx

I have a class with a list of images in it.
public class RSSClass
{
public string Title { get; set; }
public string Summary { get; set; }
public string PubDate { get; set; }
public List<ImageData> ImagePath { get; set; }
public class ImageData
{
public Uri ImageLocation
{
get;
set;
}
}
}
Hers the XAML
<ListBox Name="lstRSS">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
</StackPanel.Resources>
<TextBlock Text="{Binding Path=Title}"> </TextBlock>
<TextBlock Text="{Binding Path=PubDate}"></TextBlock>
<TextBlock Text="{Binding Path=Summary}"></TextBlock>
<ListBox x:Name="ImageListBox" ItemsSource="{Binding ImagePath}">
<DataTemplate>
<Image x:Name="image1" Source="{Binding}" MaxHeight="80" MaxWidth="120" Margin="0"></Image>
</DataTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The inner list box, ImageListBox, binds and shows the string value of the Uri. Im just not sure what to bind the image in the inner list box, image1, to?
Any help much appreciated.
Regards
Ross
You are missing <ListBox.ItemTemplate> around your <DataTemplate>. This confuses ListBox, so it thinks it is actualy an item, not a template.
Once you implement #Euphoric's resolution, bind the image1's source to ImageLocation. Example:
<Image x:Name="image1" Source="{Binding ImageLocation}" MaxHeight="80" MaxWidth="120" Margin="0"></Image>

Categories