source binding not working windows phone 7 - c#

am showing list of movie as a panorama for my windows phone 7 app. on click on each movie am showing the movie details,cast.
the movie details , cast am showing as a pivot control. movie details works fine
But when i got to show cast as , it doesnt work. i have list of cast objects. and am binding the source to a listbox in the cast pivot control , but it doesnt show any data. Please help me. below are the classes i have used. Thank you
MainViewModel.cs
public class MainViewModel
{
public ObservableCollection<ItemViewModel> MovieItems { get; set; }
}
ItemViewModel.cs
public class ItemViewModel : INotifyPropertyChanged
{
private string _title;
public string _Title
{
get { return _title; }
set
{
if (value != _title)
{
_title = value;
NotifyPropertyChanged("title");
}
}
}
private ObservableCollection<Cast> _cast;
public ObservableCollection<Cast> _Cast
{
get { return _cast; }
set
{
if (value != _cast)
{
_cast = value;
NotifyPropertyChanged("Cast");
}
}
}
..........
}
Cast.cs
public class Cast
{
public string name { get; set; }
public string imagesource { get; set; }
public Cast(string _name, string _imagesource)
{
this.imagesource = _imagesource;
this.name = _name;
}
}
for each movie i have a list of cast objects
MovieModel.cs
App.Model.MovieItems.Add(
new ItemViewModel()
{
_Title = data["title"].ToString(),
_Cast=casObs,
........
}
);
moviedetails.xaml
<ListBox Name="ListBox" Margin="0,0,-12,0" ItemsSource="{Binding _Cast}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<Canvas>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="120,5,60,3" Text="{Binding name}" TextWrapping="Wrap" FontSize="32" Style="{StaticResource PhoneTextNormalStyle}"/>
<Image Height="90" HorizontalAlignment="Left" Margin="12,10,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="90" Source="{Binding imagesource}" />
</Canvas>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Replace
NotifyPropertyChanged("title");
to
NotifyPropertyChanged("_Title");
And
NotifyPropertyChanged("Cast");
to
NotifyPropertyChanged("_Cast");
Hope it's help.

apply converter inbetween, where you need to return ImageSource/BitmapImage, instead of string

Related

Binding ObservableCollection inside an ObservableCollection

I have done many searches about this problem but still I can't figure out what is wrong with my project. The flow is like this:
I want to bind a View Model. This view model contains observablecollection that has an observablecollection in it.
Now I can bind to both observablecollections while developing without problems, but when I deploy it, the data inside the other observablecollection isn't show up.
Below is my code:
Project/Model/SubProduct.cs
class SubProducts
{
private string subName;
public string SubName
{
get
{
return subName;
}
set
{
subName = value;
}
}
}
Project/Model/Product.cs
public class Product
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
private ObservableCollection<SubProducts> subProductsSaProducts;
internal ObservableCollection<SubProducts> SubProductsSaProducts
{
get
{
return subProductsSaProducts;
}
set
{
subProductsSaProducts = value;
}
}
}
Project/Model/Category.cs
class Category
{
private string title;
public string Title
{
get
{
return title;
}
set
{
title = value;
}
}
private ObservableCollection<Product> subProducts;
public ObservableCollection<Product> SubProducts
{
get
{
return subProducts;
}
set
{
subProducts = value;
}
}
}
And this the view model that implements the models:
Project/ViewModel/CategoryViewModel.cs
class CategoryViewModel : ObservableCollection<Category>
{
public CategoryViewModel()
{
ObservableCollection<Product> pCOl1 = new ObservableCollection<Product>();
ObservableCollection<SubProducts> pCol1Sub = new ObservableCollection<SubProducts>();
SubProducts subP1 = new SubProducts();
subP1.SubName = "Lansang";
SubProducts subP2 = new SubProducts();
subP2.SubName = "Lata";
pCol1Sub.Add(subP1);
pCol1Sub.Add(subP2);
Product p1 = new Product();
p1.Name = "Pothaw";
p1.SubProductsSaProducts = pCol1Sub;
pCOl1.Add(p1);
ObservableCollection<Product> pCOl2 = new ObservableCollection<Product>();
Product p2 = new Product();
p2.Name = "Taklob sa COke";
pCOl2.Add(p2);
Add(new Category()
{
Title = "Didang",
SubProducts = pCOl1
});
Add(new Category()
{
Title = "Plastic",
SubProducts = pCOl2
});
}
}
And I use the View model in the xaml wich is the page:
<Page.DataContext>
<vm:CategoryViewModel/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<FlipView x:Name="flipView" HorizontalAlignment="Left" VerticalAlignment="Top" Width="360" ItemsSource="{Binding}" Background="#19B0F100">
<FlipView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Foreground="Black" FontSize="30" Text="{Binding Title}"/>
<ListView ItemsSource="{Binding SubProducts}" Background="#FF0C0909" Height="600">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Foreground="Red" FontSize="30" Text="{Binding Name}"/>
<ListView ItemsSource="{Binding SubProductsSaProducts}" Margin="30,0,0,0" Background="#FF933131" Height="197" Width="300">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Foreground="Yellow" FontSize="20" Text="{Binding SubName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Grid>
Now the expected data shows in development mode. In other words, the data shows only when not running the app.
My questions are:
What is wrong with my binding?
What is the proper way to do it?
Why is the data not showing when I run the app?
I'm new to C# WinRT development so any suggestions will be appreciated.
Below is the screenshot:
You should Inherit from Category class not ObservableCollection.
Also I think there's no SubProductsSaProducts property in Category class, as you bind the page to CategoryViewMode which inherit from ObservableCollection

Filter / Search binded Listbox

Hej,
ive got a ListBox binded to a ObservableCollection and now im trying to Implement a Search / Filter Function. But its not working... tried everything :(
Heres a Picture of my ListBox http://i.imgur.com/el8KF3T.png
Ok ive got the Solution thanks to Maximus's Link. Ive Updated my Code.
and heres what i tried so far my .xaml code
<ListBox Name="lstWarning" Margin="-14,3,-31,-30">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Height="62" Width="582">
<Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding DirName}" Canvas.Left="39" Canvas.Top="23"/>
<Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding CreationDate}" Canvas.Left="39" Canvas.Top="40"/>
<Label Foreground="White" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="14" Content="{Binding FileName}" Canvas.Left="39" Canvas.Top="4"/>
<Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding Extension}" Canvas.Left="224" Canvas.Top="40"/>
<Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding FileSize}" Canvas.Left="155" Canvas.Top="40"/>
<Image Source="{Binding StatusImage}" Width="30" Height="30" Canvas.Left="10" Canvas.Top="6" Stretch="Fill"/>
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And heres what if done in the TextChanged Event
private void cmdSearchWarnings_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) {
CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(lstWarning.ItemsSource);
if (!string.IsNullOrEmpty(txtSearchWarnings.Text)) {
if (isFilter) {
cv.Filter = null;
isFilter = false;
}
else {
cv.Filter = new Predicate<object>(FilterByFileName);
isFilter = true;
}
}
else {
cv.Filter = null;
isFilter = false;
}
}
private bool FilterByFileName(object _warningObj) {
if (_warningList != null) {
if (!string.IsNullOrEmpty(txtSearchWarnings.Text)) {
var warning = _warningObj as WarningItem;
return warning.FileName.Trim().Contains(txtSearchWarnings.Text);
}
}
return false;
}
And heres my WarningItem Class Code:
public class WarningItem
{
public string FullPath { get; set; }
public string DirName { get; set; }
public string FileName { get; set; }
public string FileSize { get; set; }
public string CreationDate { get; set; }
public string Extension { get; set; }
public Uri StatusImage { get; set; }
}
I am pasting simple example but similar was covered countless time you need to delve in SO. Following sample checks whether collection Names containts element which in turn containt searching word.
private ObservableCollection<string> _names = new ObservableCollection<string>()
{
"Isabel", "Michal"
};
public ObservableCollection<string> Names
{
get { return _names; }
set { _names = value; }
}
private ICollectionView View;
public MainWindow()
{
InitializeComponent();
ListBox.ItemsSource = Names;
View = CollectionViewSource.GetDefaultView(Names);
}
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{
View.Filter = x => x.ToString().ToLower().Contains(((TextBox)sender).Text.ToLower());
}
There is no need to call CollectionViewSource.GetDefaultView(Names) in TextBoxChanged event since collectionView is retrieved once and keeps reference. Take a look here.
If it comes to MVVM pattern you are not supposed to use code-behind so instead of
<TextBox TextChanged="TextBoxBase_OnTextChanged"/>
you are supposed to have
<TextBox Text="{Binding FilterText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding FilterListCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
RelayCommand

WPF Binding to member of a class within a class

My first try at C#, WPF, and MVVM. I've looked at several answers and tutorials and just cannot seem to get this right.
I have a View a Model and a ViewModel file (Actually more, but trying to simplify). In the view I want to bind a textbox to a view model member. I also want to bind a button click to a view model method.
The delegate command for Login() works fine, but I can't seem to update the ID property in Acc.ID.
What would I need to change to be able to do both?
I understand I will probably need to implement the PropertyChanged event in the ViewModel instead of the Model...I just don't understand how.
What I can do is set the DataContextto user.Acc in the code behind to directly update the model, but then I obviously cannot bind to the Login() method.
ViewModel.cs
public class LoginVM
{
private ServerInterface _serverInterface;
private ICommand _loginCommand;
private EmployeeAccount _acc;
public ICommand LoginCommand
{
get { return _loginCommand; }
}
public LoginVM()
{
Acc = new EmployeeAccount();
_serverInterface = new ServerInterface();
_loginCommand = new DelegateCommand<String>(Login);
}
public EmployeeAccount Acc { get; set; }
private void Login(object state)
{
this.Acc.ID = _serverInterface.Encrypt(this.Acc.ID);
}
}
View.xaml.cs
public partial class LoginView : Window
{
public LoginView()
{
InitializeComponent();
BindInXaml();
}
private void BindInXaml()
{
base.DataContext = new LoginVM();
}
}
Model.cs
public class EmployeeAccount : INotifyPropertyChanged
{
String _id;
public EmployeeAccount()
{
ID = "5000";
Name = "George Washington";
isAdmin = true;
Pswd = "TheyDont";
}
public String ID
{
get { return _id; }
set
{
_id = value;
this.OnPropertyChanged("ID");
}
}
public string Name { get; set; }
public Boolean isAdmin { get; set; }
public string Pswd { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(
this, new PropertyChangedEventArgs(propName));
}
}
.xaml Put in only what matters really
<TextBox x:Name="txtLogInName" Margin="60,43,42,129" TextWrapping="Wrap" Text="{Binding Path=ID, UpdateSourceTrigger=PropertyChanged}" Width="120" Grid.Column="1" Grid.Row="1"/>
<Button x:Name="btnLogIn" Content="Log on" Command="{Binding LoginCommand}" Margin="160,151,10,23" Grid.Column="1" Grid.Row="1" RenderTransformOrigin="1.667,0.545"/>
<TextBlock x:Name="txtBlockPassReset" TextAlignment="Center" Grid.Row="1" Grid.Column="1" RenderTransformOrigin="1.348,1.765" Margin="60,101,42,78">
<Hyperlink>Reset Password</Hyperlink>
</TextBlock>
<PasswordBox x:Name="pswdBoxLoginPass" Grid.Column="1" HorizontalAlignment="Left" Margin="60,72,0,0" Grid.Row="1" VerticalAlignment="Top" Width="120" Password="Password"/>
Try changing your xaml from
<TextBox x:Name="txtLogInName" Margin="60,43,42,129" TextWrapping="Wrap"
Text="{Binding Path=ID, UpdateSourceTrigger=PropertyChanged}"
Width="120" Grid.Column="1" Grid.Row="1"/>
to
<TextBox x:Name="txtLogInName" Margin="60,43,42,129" TextWrapping="Wrap"
Text="{Binding Path=Acc.ID, UpdateSourceTrigger=PropertyChanged}"
Width="120" Grid.Column="1" Grid.Row="1" />

How to do Data Binding for Textblock within a LongListselector in windows phone app?

Hi, I am trying to bind the data for text block within a LongListSelector. But I am not getting any Output for it, kindly help me.
This is my XAML code:
<phone:LongListSelector ItemsSource="{Binding ''}" x:Name="longListSelector" HorizontalAlignment="Left" Height="680" VerticalAlignment="Top" Width="446" >
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Name="name" Text="{Binding DataContext.TextContent,ElementName=page,Mode=OneWay}" Height="100" Width="100" HorizontalAlignment="Center">
</TextBlock>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
In the C# code I have parsed data which i need to display in the windows phone, in a menu format.
Part of C# code is shown below:
XDocument document = XDocument.Parse(e.Result);
var data1 = from query in document.Descendants("location")
select new Data
{
Lat = (string)query.Element("lat"),
Lag = (string)query.Element("lng")
};
foreach (var d in data1)
{
JsonParsing(d.Lat, d.Lag);
}
data1 = from query in document.Descendants("result")
select new Data
{
Country = (string)query.Element("formatted_address")
};
foreach (var d in data1)
{
// ob.JsonParsing(d.Lat, d.Lag);
//XmlParsing(d.Lat, d.Lag);
val = d.Country;
//listbox.Items.Add(val);
//StringsList.Add(val);
TextContent=val;
I want the value of the country to be shown inside the textblock, kindly help me figure this out as I am pretty new to this field, thanks.
try like this
a good reference
<DataTemplate>
<StackPanel VerticalAlignment="Top">
<TextBlock Text="{Binding Value}" />
</StackPanel>
</LongListSelector>
CodeBehind
**Add a public property only public property can be participate in databinding**
#region Public Properties
private ObservableCollection<YourModel> _collectionofValue;
public ObservableCollection<YourModel> CollectionofValues
{
get
{
return _collectionofValue;
}
set
{
_collectionofValue=value;
raisepropertyChanged("CollectionofValues");
}
}
private string _value;
public string Value
{
get
{
return _errorMessage;
}
set
{
_errorMessage = value;
RaisePropertyChanged("Value");
}
}
#endregion
**Set value to this public property when you get value**
// for single values
public void getValue()
{
value =GetXmlValue(); // your method that will return the value;
}
// as it is a collection
public void getValuestoCollection()
{
Collection.Add(new YourModel(value="SampleValue1");
Collection.Add(new YourModel(value="SampleValue1");
Collection.Add(new YourModel(value="SampleValue1");
Collection.Add(new YourModel(value="SampleValue1");
}
YourModel
// the collection of this model is binded to the LongListSelector.
public class ModelName
{
public string Values {get;set;}
}
reference
<phone:LongListSelector ItemsSource="{Binding Items}" x:Name="longListSelector" HorizontalAlignment="Left" Height="680" VerticalAlignment="Top" Width="446" >
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Name="name" Text="{Binding Path=TextContent}" Height="100" Width="100" HorizontalAlignment="Center">
</TextBlock>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
Your C# algm should be:
i) Have a viewmodel class
public class MyViewModel
{
public ObservableCollection<MyDataItem> Items {get; set;}
public MyViewModel()
{
Items=new ObservableCollection<MyDataItem>();
loop //add your items to your 'Items' property so that you can bind this with LongListSelector ItemsSource
{
Items.Add(new MyDataItem("mystring"));
}
}
}
public class MyDataItem
{
public MyDataItem(string s)
{
TextContent=s;
}
public string TextContent {get;set;}
}
ii) Create an instance to ViewModel class and set DataContext
// write this in the constructor of the page which contains the LongListSelector
public MyViewModel vm;
constructor()
{
vm=new MyViewModel();
this.DataContext=vm;
}

DataTemplate is not generating ListItemBox

I want to generate ListItemBox using DataTemplate but items are not generating. Please guide me where is the mistake. I have following code in MainWindow.xaml.
<Window x:Class="Offline_Website_Downloader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:bd="clr-namespace:Offline_Website_Downloader"
Title="Offline Website Downloader" Background="#f5f6f7" Height="500" Width="800"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<bd:BindingController x:Key="BindingControllerKey" />
<DataTemplate x:Key="DownloadedWebsitesListBox">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Width="Auto">
<TextBlock FontWeight="Bold" FontSize="18" Width="480">
<Hyperlink NavigateUri="http://google.com">
<Label Content="{Binding Path=WebsiteTitle}" />
</Hyperlink>
</TextBlock>
<TextBlock Width="132" TextAlignment="right">
<TextBlock Text="Remaining Time: "/>
<TextBlock Name="TimeRemaining" Text="js"/>
</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<ProgressBar Name="progress1" Maximum="100" Minimum="0" Value="30" Background="#FFF" Width="612" Height="10" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" Width="450">Status: <TextBlock Text="{Binding Path=Status}"/></TextBlock>
<TextBlock Width="162" TextAlignment="right">
<TextBlock Text="Downloading Speed: "/>
<TextBlock Name="DownloadingSpeed" Text="{Binding Path=DownloadingSpeed}"/>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox Width="Auto"
Name="WebsiteList"
Grid.Column="1"
Grid.Row="2"
Grid.RowSpan="2"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource DownloadedWebsitesListBox}"
Margin="0,0,0,0">
</ListBox>
</Grid>
</window>
and MainWindow.xaml.cs
BindingController bc = new BindingController();
public MainWindow()
{
InitializeComponent();
bc.DownloadingSpeed = "40kb/s";
bc.WebsiteTitle = "WebsiteTitle";
bc.Status = "Downloading";
DataContext = bc;
}
and BindingController.cs
public class BindingController
{
public BindingController()
{
}
private string _WebsiteTitle;
public string WebsiteTitle
{
set { _WebsiteTitle = value; }
get { return _WebsiteTitle; }
}
private string _Status;
public string Status
{
set { _Status = value ; }
get { return _Status ; }
}
private string _DownloadStartDate;
public string DownloadStartDate
{
set { _DownloadStartDate = value; }
get { return _DownloadStartDate ; }
}
private string _DownloadingSpeed = "0 kb/s";
public string DownloadingSpeed
{
set { _DownloadingSpeed = value; }
get { return _DownloadingSpeed; }
}
}
Your problem is that you're binding a ListBox to an object that contains several properties, but really only represents a single object/state. The ListBox expects to display a list of items (i.e. IList, IBindingList, IEnumerable, ObservableCollection).
Assuming you want to display more than one download at a time, which I'm assuming given that you're using a ListBox, I would refactor the download properties into a separate class. You will also need to implement INotifyPropertyChanged on your properties so that when the values are changed, they will be shown in the UI.
public class Download : INotifyPropertyChanged
{
private string _WebsiteTitle;
public string WebsiteTitle
{
get { return _WebsiteTitle; }
set
{
if (_WebsiteTitle == value)
return;
_WebsiteTitle = value;
this.OnPropertyChanged("WebsiteTitle");
}
}
private string _Status;
public string Status
{
get { return _Status; }
set
{
if (_Status == value)
return;
_Status = value;
this.OnPropertyChanged("Status");
}
}
private string _DownloadStartDate;
public string DownloadStartDate
{
get { return _DownloadStartDate; }
set
{
if (_DownloadStartDate == value)
return;
_DownloadStartDate = value;
this.OnPropertyChanged("DownloadStartDate");
}
}
private string _DownloadingSpeed = "0 kb/s";
public string DownloadingSpeed
{
get { return _DownloadingSpeed; }
set
{
if (_DownloadingSpeed == value)
return;
_DownloadingSpeed = value;
this.OnPropertyChanged("DownloadingSpeed");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if(this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The new BindingController:
public class BindingController
{
public BindingController()
{
this.Downloads = new ObservableCollection<Download>();
}
public ObservableCollection<Download> Downloads { get; private set; }
}
Setting up the bindings in XAML:
<ListBox Width="Auto"
Name="WebsiteList"
Grid.Column="1"
Grid.Row="2"
Grid.RowSpan="2"
ItemsSource="{Binding Downloads}"
ItemTemplate="{StaticResource DownloadedWebsitesListBox}"
Margin="0,0,0,0">
</ListBox>
Initializing the collection in MainWindow
Download download = new Download();
download.DownloadingSpeed = "40kb/s";
download.WebsiteTitle = "WebsiteTitle";
download.Status = "Downloading";
bc.Downloads.Add(download);
this.DataContext = bc;

Categories