I am trying to bind user control inside listbox, but it seems I am doing something wrong, Though I followed How to bind data user control inside listbox WP8 but this couldn't help.
Here what I am doing in user control
<Grid x:Name="LayoutRoot" Background="Transparent" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Source="Images/download.png" Width="30" Height="30" VerticalAlignment="Top" Grid.Column="0"/>
<ProgressBar Grid.Row="0" Grid.Column="1" x:Name="prg" VerticalAlignment="Top" />
<TextBlock x:Name="TextBlock" Foreground="Black" Text="{Binding Text}" Grid.Row="0" Grid.Column="2" VerticalAlignment="Top" FontSize="20" HorizontalAlignment="Left" />
</Grid>
and code behind for user control
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(SuraWithProgressBar),
new PropertyMetadata(null));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value);}
}
The usage
<ListBox x:Name="lsbQuranData" Grid.Row="1" Foreground="Black" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<local:SuraWithProgressBar Text="{Binding SuraTName, ElementName=SuraWithProgressBar}"></local:SuraWithProgressBar>
<Line X1="0" X2="480" Y1="0" Y2="0" VerticalAlignment="Bottom" StrokeThickness="2" Stroke="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and code behind for usage
lsbQuranData.ItemsSource = App.Chapter;
Let me mention that "App.Chapter" contain "SuraTName" which is binded to Text property of user control. The user control is added in list box, but the text is not displayed.
Converter is a good thing for debug binding issue =>
public sealed class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
Finally, I came up with following solution.
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof(string),
typeof(SuraWithProgressBar),
new PropertyMetadata(null));
I changed the "Text" to "SuraTName" and it worked!!
Related
I am facing issues getting the string values using e.ClickedItem.
Here's how my ListView looks like:
<ListView
x:Name="PoemListView"
AutomationProperties.AutomationId="PoemListView"
AutomationProperties.Name="Poems In Item"
TabIndex="1"
ItemsSource="{Binding Item.Poems}"
IsItemClickEnabled="True"
ItemClick="PoemView_PoemClick"
SelectionMode="None"
SelectionChanged="PoemSelectionChanged"
IsSwipeEnabled="False" Padding="0,0,0,0" Margin="0,0,0,0"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="0,0,0,27.5" HorizontalAlignment="Left" ScrollViewer.VerticalScrollBarVisibility="Hidden">
<!--<CheckBox x:Name="PoemCheckbox" Checked="ContentChecked" Unchecked="ContentUnchecked"/>-->
<TextBlock x:Uid="PoemId" Name="PoemId" Text="{Binding PoemId}" DataContext="{Binding}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" TextWrapping="WrapWholeWords"/>
<TextBlock x:Uid="PoemTitleId" Text="{Binding PoemTitle}" FontSize="{Binding ElementName=FontSlider, Mode=OneWay, Path=Value}" DataContext="{Binding}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" Foreground="{ThemeResource PhoneMidBrush}" TextWrapping="WrapWholeWords"/>
<TextBlock x:Uid="PoemMeanId" Text="{Binding PoemMean}" DataContext="{Binding}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" TextWrapping="WrapWholeWords"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is the code behind the xaml page:
private void PoemView_PoemClick(object sender, ItemClickEventArgs e)
{
TextBlock PoemId = e.ClickedItem as TextBlock;
this.Frame.Navigate(typeof(Favorite), (e.ClickedItem as TextBlock));
On LoadState event of the Favorite page, I have added the below code:
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
string poem = e.NavigationParameter as string;
if (string.IsNullOrEmpty(poem))
{
FavText.Text = "no favorite text";
}
else { FavText.Text = poem;
}
}
The problem is in the LoadState while the e.NavigationParameter is loaded with the strings passed to it, the string poem is not loading properly. Therefore, the FavText.Text is always returning the "no favorite text".
Anyone has a clue on how to fix this?
Your PoemId is probably null when you cast e.ClickedItem as TextBlock
Try this
Poem poem = e.ClickedItem as Poem;
this.Frame.Navigate(typeof(Favorite), poem);
Instead of casting e.ClickedItem as TextBlock, I updated the code as below which worked perfectly fine:
var type = ((PoemItem)e.ClickedItem).PoemTitle;
this.Frame.Navigate(typeof(Favorite), type);
I want to create report of students in windows phone 8 app.
there are 3 row and 4 columns
structure is like as follow
student1 student2 student3
subject1
subject2
subject3
Total
marks
now the student1, student2 are names of student should come dynamically from windows azure database.
all the marks are in database for perticular students. these marks should get display in front of perticular student for perticular subject.
All data is present in database. How to show it in table form?
I think a simple Grid control containing some textblocks would be just fine. You can define it in XAML really easily:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" ... />
<TextBlock Grid.Row="1" Grid.Column="0" ... />
<TextBlock Grid.Row="2" Grid.Column="0" ... />
...
</Grid>
The only think you need to look out for is how the heights and widths are defined. Essentially there are 3 types of height/width:
Static: Defined with a number and measured in pixels
Automatic: Defined by the keyword Auto and changes dynamically according to content size
"Fill the rest": Defined by the star * symbol and makes the row/column fill the rest of the space available in the grid.
Check out the MSDN documentation for the Grid control for more info.
You can set View as Shown Below:
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListBox x:Name="stu" Grid.RowSpan="4" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<TextBlock Text="{Binding name}"></TextBlock>
<TextBlock Text="{Binding s1}" TextAlignment="Center"></TextBlock>
<TextBlock Text="{Binding s2}" TextAlignment="Center"></TextBlock>
<TextBlock Text="{Binding s3}" TextAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock></TextBlock>
<TextBlock Grid.Row="1" Text="Subject1"></TextBlock>
<TextBlock Grid.Row="2" Text="Subject2"></TextBlock>
<TextBlock Grid.Row="3" Text="Subject3"></TextBlock>
</Grid>
CS:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
List<data> obj = new List<data>();
obj.Add(new data("Student1", "10", "20", "30"));
obj.Add(new data("Student2", "0", "10", "20"));
obj.Add(new data("Student3", "20", "30", "40"));
obj.Add(new data("Student4", "30", "40", "50"));
obj.Add(new data("Student5", "40", "50", "60"));
stu.ItemsSource = obj;
}
public class data
{
public string name { get; set; }
public string s1 { get; set; }
public string s2 { get; set; }
public string s3 { get; set; }
public data() { }
public data(string name, string s1, string s2, string s3)
{
this.name = name;
this.s1 = s1;
this.s2 = s2;
this.s3 = s3;
}
}
Here You just needed to have data from Azure Database. from above implementation you can have view like as under with scrolling data of Students.
You Have to Use 1st Listbox As Column and Set ItemSource Property
and
another ListBox For the Row of the Object and set ItemSource Property.
I have a Metro App with a ListView that contains this definition:
<ListView Grid.Row="0" x:Name="lv" CanDragItems="True" CanReorderItems="True" IsTabStop="True" SelectionMode="Extended" VirtualizingStackPanel.VirtualizationMode="Recycling">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ElementName=lv, Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="tb1" Foreground="{StaticResource SecondaryColourBrush}" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="4" x:Name="tb2" Foreground="{StaticResource SecondaryColourBrush}" HorizontalAlignment="Right"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Name="tb3" Foreground="{StaticResource QuadColourBrush}" HorizontalAlignment="Stretch" TextTrimming="WordEllipsis"/>
<TextBlock Grid.Column="1" x:Name="tb4" Foreground="{StaticResource QuadColourBrush}" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When the ListView has an item selected, I want to change the Foreground of tb1 and tb2 ONLY to White. How do I go about doing this?
I tried overriding Themed Brushes and VisualStateGroup SelectionStates for Selected, which hasn't helped. A working code example would be appreciated.
Finally RESOLVED this, thanks to this article for giving me the idea:
http://blog.davemdavis.net/2012/11/12/controlling-the-datatemplate/
Created a BooleanToColourConverter
public sealed class BooleanToColourConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (value is bool && (bool)value) ? AppResources.TertiaryColourBrush : AppResources.PrimaryColourBrush;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value is SolidColorBrush && ((SolidColorBrush)value).Color == AppResources.TertiaryColourBrush.Color;
}
}
Added this in App.xaml
<common:BooleanToColourConverter x:Key="BooleanToColourConverter"/>
Then used it like this:
Foreground="{Binding Tag, Converter={StaticResource BooleanToColourConverter}, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}"
I have a TextBlock in the datatemplate of ListFooterTemplate of LongListSelector,to which I give a Collection as Itemssource,I want to bind the Text Property of TextBlock to a string in the Codebehind. Please tell me how to do it. Here is the xaml.
I am using VS2012 and WP8 SDK.
<toolkit:LongListSelector ItemsSource="{Binding Collection}">
<toolkit:LongListSelector.ListFooterTemplate>
<DataTemplate>
<TextBlock Text= "{Binding footertext}" />
</DataTemplate>
</toolkit:LongListSelector.ListFooterTemplate>
</toolkit:LongListSelector>
footertext is the string I have defined in the codebehind. I have implemented INotifyPropertyChanged also but footer doesnt show the text.
Just guessing here, but the most likely reason you're not seeing any footer is that you're not binding to the right object. The LongListSelector is binding to properties on its DataContext. If the Collection property lives on a different object than the footertext property that would cause this problem.
Here's some sample code that works for me:
Code-behind
namespace LongListSelector
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
SomeText = "This is my footer text from the code-behind";
}
public string SomeText { get; private set; }
}
}
XAML
<phone:PhoneApplicationPage
x:Class="LongListSelector.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LongListSelector"
mc:Ignorable="d"
x:Name="page"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.DataContext>
<local:SampleData/>
</phone:PhoneApplicationPage.DataContext>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector ItemsSource="{Binding Collection}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
<phone:LongListSelector.ListFooterTemplate>
<DataTemplate>
<TextBlock Text="{Binding SomeText,ElementName=page}"/>
</DataTemplate>
</phone:LongListSelector.ListFooterTemplate>
<phone:LongListSelector.ListHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.HeaderText, ElementName=page, Mode=OneWay}"/>
</DataTemplate>
</phone:LongListSelector.ListHeaderTemplate>
</phone:LongListSelector>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
Sample data object
using System.Collections.ObjectModel;
namespace LongListSelector
{
public class SampleData
{
public SampleData()
{
Collection = new ObservableCollection<string>( new string[] { "Item 1", "Item 2", "Item 3" } );
HeaderText = "This is my header text";
}
public ObservableCollection<string> Collection { get; private set; }
public string HeaderText { get; private set; }
}
}
Note that the ItemsSource property on the LongListSelector binds to the DataContext (as does the header) while footer binds to a property in the code-behind class.
Hope this helps.
How can i get access to longlistselector items.
My XAML is:
<Grid x:Name="ContentPanel" Grid.Row="1" HorizontalAlignment="Left" Height="Auto" Margin="30,20,0,0" Grid.RowSpan="2" VerticalAlignment="Top" Width="420">
<phone:LongListSelector Name="longList" HorizontalAlignment="Left" Height="Auto" Margin="0" VerticalAlignment="Top" Width="420">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="210" />
<ColumnDefinition Width="210" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="160" />
</Grid.RowDefinitions>
<Image Name="first" Width="210" Margin="0" Source="{Binding ImageName}" Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Image Name="second" Width="210" Margin="0" Source="{Binding ImageName}" Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
I want to get access of image objects first & second
I need to assign source of these two image objects from list of class which contain ImageName string as variable(holds path of jpg image) consecutive and then next two to next row and so on..
Add a new folder to the solution and rename the folder to "Model"
Then add a new class with the name "ImageSourceClass"
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApp.Model
{
public class ImageSourceClass
{
public string ImageUrl { get; set; }
public ImageSourceClass(string imageUrl)
{
this.ImageUrl = imageUrl;
}
}
public class ImageData : ObservableCollection<ImageSourceClass>
{
public ImageData()
{
Add(new ImageSourceClass("/Assets/Images/Fruits.jpg"));
Add(new ImageSourceClass("/Assets/Images/Beignets.jpg"));
Add(new ImageSourceClass("/Assets/Images/Dessert.jpg"));
Add(new ImageSourceClass("/Assets/Images/Pretzel.jpg"));
Add(new ImageSourceClass("/Assets/Images/Shrimp.jpg"));
Add(new ImageSourceClass("/Assets/Images/SteakSandwich.jpg"));
}
}
}
MainPage.xaml
Added the below namespace to MainPage.xaml
Note : [According to your solution name namespace may vary]
xmlns:MyModel="clr-namespace:TestApp.Model"
<Grid x:Name="LayoutRoot" Background="Transparent" >
<Grid.Resources>
<MyModel:ImageData x:Key="imageDatasource"></MyModel:ImageData>
</Grid.Resources>
<phone:LongListSelector x:Name="lstRestoItems" ItemsSource="{StaticResource imageDatasource}" LayoutMode="List">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageUrl}" Height="100" Width="100" HorizontalAlignment="Left"></Image>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
We are done , now just clean and re-build your application and press f5