How to correct bind property to textbox? - c#

I write these code in mainpage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBox x:Name="xxx" Text="{Binding Test}" TextChanged="xxx_TextChanged" />
<Button x:Name="click" Click="click_Click" Content="click" />
</StackPanel>
</Grid>
And these in mainpage.xaml.cs
private string test;
public string Test
{
get { return test; }
set
{
if (test != value)
{
test = value;
OnPropertyChanged("Test");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
// Constructor
public MainPage()
{
InitializeComponent();
}
private void xxx_TextChanged(object sender, TextChangedEventArgs e)
{
Debug.WriteLine(Test);
Debug.WriteLine(test);
}
But Test isn't binded to textbox, when I write smth to textbox Test isn't changed.
What I doing wrong and how to correct that ?

Try setting BindingMode to TwoWay:
Text="{Binding Test, Mode=TwoWay}"
The other thing I've noticed, is that your binding to work need DataContext to be set, but you don't do that in your example. One way to do this would be something like this:
public MainPage()
{
InitializeComponent();
ContentPanel.DataContext = this;
}
If staying in Xaml is preferred, you can use RelativeSource property to bind to your page in Xaml, without setting DataContext:
Text="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, //or Page
Path=Test, Mode=TwoWay}"
Another thing, Test will be set not after every character you type in your TextBox, but after user will finish editing text, for example by switching active control to next one.

Related

binding in wpf doesn't work, can't see why

I have a wpf app I'm using some xaml code that should let me view pdf files, I just started to use data biding and don't figure way this not works for me.
here m XAML:
<Grid>
<telerik:RadPdfViewerToolBar RadPdfViewer="{Binding ElementName=pdfViewer, Mode=OneTime}" SignaturePanel="{Binding ElementName=signaturePanel, Mode=OneTime}"/>
<telerik:SignaturePanel x:Name="signaturePanel" PdfViewer="{Binding ElementName=pdfViewer, Mode=OneWay}" Grid.Row="1"/>
<telerik:RadPdfViewer x:Name="pdfViewer" DocumentSource="{Binding Path=PathOfPdf, Mode=TwoWay}" DataContext="{Binding CommandDescriptors, ElementName=pdfViewer}" telerik:RadPdfViewerAttachedComponents.RegisterSignSignatureDialog="True" telerik:RadPdfViewerAttachedComponents.RegisterFindDialog="True" Grid.Row="2" telerik:RadPdfViewerAttachedComponents.RegisterSignaturePropertiesDialog="True" telerik:RadPdfViewerAttachedComponents.RegisterContextMenu="True"/>
<Grid>
And here code behind:
public partial class Page2 : Page, INotifyPropertyChanged
{
public Page2()
{
InitializeComponent();
DataContext = this;
}
private string _pathOfPdf= #"D:\MyFile.pdf";
public string PathOfPdf
{
get{ return _pathOfPdf; }
set{
if (_pathOfPdf != value)
{
_pathOfPdf = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
If I'm not using Biding it works fine. I if I do(on XAML):
DataContext="D:\MyFile.pdf" it shows the pdf
You need to either set the DataContext of the control or the source of the binding to the Page where the source property is defined:
<telerik:RadPdfViewer x:Name="pdfViewer"
DocumentSource="{Binding Path=PathOfPdf, RelativeSource={RelativeSource AncestorType=Page}}" />

ComboBox Selected Item not updating

Problem
I am trying to bind a ComboBox's SelectedItem to a custom class but this does not update when the property is changed.INotifyPropertyChanged is implemented.
The DataContext
The DataContext is a custom class which contains many properties, but an extract of this is below. You can see it implements INotifyPropertyChanged and this called when the two properties are changed.
public class BctsChange : INotifyPropertyChanged
{
#region declarations
private byContact _Engineer;
public byContact Engineer
{
get { return _Engineer; }
set
{
_Engineer = value;
NotifyPropertyChanged("Engineer");
OnEngineerChanged();
}
}
private BctsSvc.DOSets _LeadingSet;
public BctsSvc.DOSets LeadingSet
{
get { return _LeadingSet; }
set { _LeadingSet = value; NotifyPropertyChanged("LeadingSet"); }
}
#endregion
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public BctsChange()
{
Engineer = new byContact(Environment.UserName);
}
private void OnEngineerChanged()
{
if (Engineer != null)
{
BctsSvc.DOSets leadSet = GetLeadingSetFromDeptCode(Engineer.DeptCode);
if (leadSet == null) return;
LeadingSet = leadSet;
}
}
private static BctsSvc.DOSets GetLeadingSetFromDeptCode(string DeptCode)
{
BctsSvc.BctsServiceSoapClient svc = new BctsSvc.BctsServiceSoapClient();
BctsSvc.DOSets setX = svc.GetSetFromDeptCode(DeptCode);
return setX;
}
}
The Window XAML
I have several controls on the window, but to keep the code simple I believe the following extract will suffice.
<Window x:Class="MyNamespace.wdSubmit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:MyNamespace"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Name="ucReqForm"
Title="wdSubmit" >
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<GroupBox Header="Engineer Details" Name="grpOwnerDetails" >
<StackPanel Orientation="Vertical">
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="35"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding Engineer.FullName, FallbackValue='Please select an engineer by clicking →', Mode=OneWay}" Margin="5,0" IsEnabled="True" FontStyle="Italic" />
<Button Content="{StaticResource icoSearch}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Column="1" Height="23" Name="btnSelectEngineer" Margin="0,0,5,0" HorizontalAlignment="Stretch" ToolTip="Search for an engineer responsible" Click="btnSelectEngineer_Click" />
</Grid>
<ComboBox Height="23" x:Name="ddSet2" Margin="5,0" ItemsSource="{Binding LeadingSets, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" SelectedItem="{Binding LeadingSet, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SetName}" ToolTip="{Binding HelpInfo}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<my:LabelledDropdown Height="23" x:Name="ddSet" Margin="5,0" ItemsSource="{Binding LeadingSets, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" SelectedItem="{Binding LeadingSet, Mode=TwoWay,NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}" Label="e.g. BodyHardware">
<my:LabelledDropdown.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SetName}" ToolTip="{Binding HelpInfo}"/>
</DataTemplate>
</my:LabelledDropdown.ItemTemplate>
</my:LabelledDropdown>
</StackPanel>
</GroupBox>
</StackPanel>
</Window>
The above extract contains:
A Label that contains a contact's name, and a button to search for a contact, bound to the FullName of the Engineer
A ComboBox that contains departments within the company, bound to an ObservableCollection<DOSets>, which contains a list of departments
Two ComboBoxes, one which is a custom one and the other which is temporary to ensure the bug is not within the control. These are Databound to LeadingSet
Window Code Behind
In the code behind I set the DataContext to CurrentChange. When the user wants to select a different Engineer then this will update the selected department for the engineer in CurrentChange.
When the user changes the engineer, the data binding for the engineer is updated, but the selected department (Leading Set) isn't.
//Usings here
namespace MyNamespace
{
public partial class wdSubmit : Window, INotifyPropertyChanged
{
private BctsSvc.BctsServiceSoapClient svc;
private BctsChange _CurrentChange;
public BctsChange CurrentChange
{
get { return _CurrentChange; }
set { _CurrentChange = value; OnPropertyChanged("CurrentChange"); }
}
private List<BctsSvc.DOSets> _LeadingSets;
public List<BctsSvc.DOSets> LeadingSets
{
get
{
return _LeadingSets;
}
}
public wdSubmit()
{
InitializeComponent();
svc = new BctsSvc.BctsServiceSoapClient();
_LeadingSets = svc.GetLeadSets().ToList();
OnPropertyChanged("LeadingSets");
this._CurrentChange = new BctsChange();
this.DataContext = CurrentChange;
CurrentChange.PropertyChanged += new PropertyChangedEventHandler(CurrentChange_PropertyChanged);
}
void CurrentChange_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged("CurrentChange");
OnPropertyChanged(e.PropertyName);
}
private void btnSelectEngineer_Click(object sender, RoutedEventArgs e)
{
byContact newContact = new frmSearchEngineer().ShowSearch();
if (newContact != null)
{
CurrentChange.Engineer = newContact;
PropertyChanged(CurrentChange, new PropertyChangedEventArgs("LeadingSet"));
PropertyChanged(CurrentChange.LeadingSet, new PropertyChangedEventArgs("LeadingSet"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(CurrentChange, new PropertyChangedEventArgs(propertyName));
}
}
}
I've realised the problem may be due to the LeadingSet, returned when the engineer is changed, being a different instance to that in the ObservableCollection.

WPF ~ Trouble with Binding & INotifyPropertyChanged

WPF n00bie here, trying to get his UI to work properly.
So I made this test example. The textblock bound to HeaderText1 changes correctly at the launch of the app, but the textblock bound to HeaderText2 doesn't update after clicking the button.
What am I doing wrong? Thanks in advance!!
<Window x:Class="DataBinding.DataContextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataContextSample" Height="142.596" Width="310">
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />
<Button Name="btnUpdateSource" Click="btnUpdateSource_Click" Margin="5,0" Padding="5,0">*</Button>
</WrapPanel>
<TextBlock Text="{Binding Path=DataContext.HeaderText}"></TextBlock>
<TextBlock Text="{Binding Path=DataContext.HeaderText2}"></TextBlock>
</StackPanel>
</Window>
Main window class:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DataBinding
{
public partial class DataContextSample : Window
{
public string HeaderText { set; get; }
public DataContextSample()
{
HeaderText = "YES";
InitializeComponent();
this.DataContext = this;
}
private void btnUpdateSource_Click(object sender, RoutedEventArgs e)
{
BindingExpression binding = txtWindowTitle.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
Source source = new Source();
source.HeaderText2 = "YES2";
}
}
}
And the INotifyPropertyChanged class
using System.ComponentModel;
namespace DataBinding
{
public class Source : INotifyPropertyChanged
{
public string HeaderText2 { set; get; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
}
First of all you are doing many things wrong.
You should not be using the window as it's own datacontext, you should have a viewmodel that you set.
You should not be using event handlers in the view to manipulate the viewmodel. You should bind the button to a command.
Your source seems to be a "viewmodel", consider renaming it to MainWindowViewModel (for clarity) and then do this.
public class MainWindowViewModel : INotifyPropertyChanged
{
private string headerText;
private string headerText2;
private ICommand updateHeaderText2;
public string HeaderText
{
set
{
return this.headerText;
}
get
{
this.headerText = value;
// Actually raise the event when property changes
this.OnPropertyChanged("HeaderText");
}
}
public string HeaderText2
{
set
{
return this.headerText2;
}
get
{
this.headerText2 = value;
// Actually raise the event when property changes
this.OnPropertyChanged("HeaderText2");
}
}
public ICommand UpdateHeaderText2
{
get
{
// Google some implementation for ICommand and add the MyCommand class to your solution.
return new MyCommand (() => this.HeaderText2 = "YES2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
And set this viewmodel to the datacontext of your window.
this.DataContext = new MainWindowViewModel();
And then in your xaml you should bind to the viewmodel as such
<Window x:Class="DataBinding.DataContextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataContextSample" Height="142.596" Width="310">
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<!-- Not sure what this binding is? -->
<TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />
<Button Name="btnUpdateSource" Command="{Binding UpdateHeaderText2}" Margin="5,0" Padding="5,0">*</Button>
</WrapPanel>
<TextBlock Text="{Binding HeaderText}"></TextBlock>
<TextBlock Text="{Binding HeaderText2}"></TextBlock>
</StackPanel>
</Window>
You set the DataContext to this (the window). You don't have a property named HeaderText2 in the DataContext so the second binding won't work.
I'd do this (without changing your code too much, in reality I'd do a proper MVVM approach):
public partial class DataContextSample : Window
{
public Source Source { get; set; }
public string HeaderText { set; get; }
public MainWindow()
{
InitializeComponent();
HeaderText = "YES";
Source = new Source { HeaderText2 = "YES" };
DataContext = this;
}
private void btnUpdateSource_Click(object sender, RoutedEventArgs e)
{
BindingExpression binding = txtWindowTitle.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
Source.HeaderText2 = "YES2";
}
}
I added a new property called Source which is of type Source. Set its initial HeaderText2 to the same "YES" in the constructor and in the button click change that to "YES2".
You have to change your Source class as well, to actually notify about changes:
public class Source : INotifyPropertyChanged
{
private string _headerText2;
public string HeaderText2
{
get { return _headerText2; }
set
{
_headerText2 = value;
OnPropertyChanged("HeaderText2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
And then in your XAML:
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />
<Button Name="btnUpdateSource" Click="btnUpdateSource_Click" Margin="5,0" Padding="5,0">*</Button>
</WrapPanel>
<TextBlock Text="{Binding Path=HeaderText}"></TextBlock>
<TextBlock Text="{Binding Path=Source.HeaderText2}"></TextBlock>
</StackPanel>
Well there are a few issues with your code.
First of all, you never assign your "Source" to a datacontext, so there's no way for your second TextBlock to find the value of "HeaderText2".
If however you would assign your "Source" to the textblocks datacontext then we could fetch the value of "HeaderText2". Consider the code below
<Window x:Class="DataBinding.DataContextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataContextSample" Height="142.596" Width="310">
<StackPanel Margin="15">
<WrapPanel>
<TextBlock Text="Window title: " />
<TextBox Name="txtWindowTitle" Text="{Binding Title, UpdateSourceTrigger=Explicit}" Width="150" />
<Button Name="btnUpdateSource" Click="btnUpdateSource_Click" Margin="5,0" Padding="5,0">*</Button>
</WrapPanel>
<TextBlock Text="{Binding Path=HeaderText}"></TextBlock>
<TextBlock Name="TextBlock2" Text="{Binding Path=HeaderText2}"></TextBlock>
</StackPanel>
</Window>
We have given your second Textblock a name, "TextBlock2" and also removed the "Datacontext"-part from your binding.
Then we have moved the Creation of your "Source" object from the button event to the windows constructor (there is no need to make a new one everytime we click a button when all we want to do is to update a property)
public partial class DataContextSample : Window
{
public string HeaderText { set; get; }
private Source source { get; set; }
public DataContextSample()
{
...
source = new Source();
TextBlock2.DataContext = source;
...
}
...
}
And then in your buttons click-event we assign your databound property a value of "YES2".
private void btnUpdateSource_Click(object sender, RoutedEventArgs e)
{
...
source.HeaderText2 = "YES2";
}
There is however one more detail. Your class "Source" does implement "INotifyPropertyChanged", but it never "uses" it. By that I mean, that when you assign a value to your property "HeaderText2" you never actually "notify" the UI that something has changed with it, and thus the UI will not fetch the new value. Consider the code below:
public class Source : INotifyPropertyChanged
{
public string HeaderText2 { set
{
headerText2 = value;
OnPropertyChanged("HeaderText2");
}
get
{
return headerText2;
}
}
string headerText2;
...
}
So let's take a look at what we've done with the property "HeaderText2". Everytime the "HeaderText2" gets a value assigned, it will first save the value in a privat property (so that we can read from it later). But in addition to that we also call the "OnPropertyChanged" method with our Propertys name. That method will in turn check if anyone is "listening" to our "PropertyChanged"-event (and since we have a databinding on the current object, someone is listening), and create a new event.
Now we have assigned a datasource to your textblock with a path to "HeaderText2", we are notifying all listeners when we update "HeaderText2" on the datasource and we are updating "HeaderText2" on the buttons click event.
Happy coding!

NotifySourceUpdated & Binding.SourceUpdated not working

My event below (OnSourceUpdated) is not getting handled.
XAML:
<StackPanel x:Name="MyStackPanel"
Orientation="Horizontal"
DockPanel.Dock="Top">
<TextBox Text="{Binding Side, Mode=TwoWay}"
Width="100"/>
<TextBlock Background="Yellow"
Text="{Binding Side, Mode=OneWay,
NotifyOnSourceUpdated=True}"
Width="100"
SourceUpdated="OnSourceUpdated"
Binding.SourceUpdated="OnSourceUpdated"/>
</StackPanel>
C#:
....
MyStackPanel.DataContext = new MyItemClass() { Side = "Test" };
....
private void OnSourceUpdated(Object sender, DataTransferEventArgs args)
{
var i = args.Property;
}
public class MyItemClass : INotifyPropertyChanged
{
private string _side;
public string Side
{
get { return _side; }
set
{
_side = value;
OnPropertyChanged("Side");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
I have all the relevant settings done like NotifyOnSourceUpdated & SourceUpdated & Binding.SourceUpdated etc.
From msdn: Binding.SourceUpdated attached event occurs when a value is transferred from the binding target to the binding source, but only for bindings with the NotifyOnSourceUpdated value set to true
In the Binding of TextBlock, there is no value transfer from the binding target (TextBlock.Text) to the binding source (Side). Thus SourceUpdated cannot be fired.
Instead SourceUpdated can be fired on the first binding. Indeed here the target binding TextBox.Text can change the binding source (Side).
Maybe I'm missing something, but I'm thinking your approach to updating is a bit strange. Is there a reason you're not just going with
<TextBlock Text="{Binding foo, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" ... />
If you're just interested in updates coming from source, that's normally the way of doing it. Calling
OnPropertyChanged( "PropertyName" )
covers the rest.

How to bind the view model to the view

I am having trouble binding my View Model to my View. I am a beginner with MVVM, but I believe I am implementing my system (almost) correctly. I have a Model that contains data, which I am getting in my View Model, and then when my page is navigated to, I am attempting to grab that View Model data and binding it to the View.
My issue is that I have a ListBox in my View with 3 objects per item, and I cannot seem to bind to it correctly for each item in my list.
MainPage.xaml
<ListBox x:Name="FavoritesListBox" ItemsSource="{Binding FavoriteItems}"
SelectionChanged="FavoritesListBox_SelectionChanged">
<StackPanel Orientation="Horizontal" Margin="12,0,12,0">
<Image x:Name="favicon" Source="{Binding Favicon}"
Width="50" Height="50"/>
<StackPanel>
<TextBlock x:Name="favoritesName" Text="{Binding Name}"
FontSize="{StaticResource PhoneFontSizeExtraLarge}"/>
<TextBlock x:Name="favoritesAddress"
Text="{Binding Address}" Margin="12,0,0,0"/>
</StackPanel>
</StackPanel>
</ListBox>
MainPage.xaml.cs
public FavoritesPage()
{
InitializeComponent();
// Set the data context of the listbox control to the sample data
FavoritesListBox.DataContext = App.ViewModel;
}
App.xaml.cs
private static MainViewModel viewModel = null;
public static MainViewModel ViewModel
{
get
{
// Delay creation of the view model until necessary
if (viewModel == null)
viewModel = new MainViewModel();
return viewModel;
}
}
MainViewModel.cs
public ObservableCollection<ItemViewModel> FavoriteItems { get; private set; }
public MainViewModel()
{
//FavoriteItems = new ObservableCollection<ItemViewModel>();
FavoriteItems = Settings.FavoritesList.Value;
}
Settings.cs (The Model)
public static Setting<ObservableCollection<ItemViewModel>> FavoritesList =
new Setting<ObservableCollection<ItemViewModel>>(
"Favorites",
new ObservableCollection<ItemViewModel>());
ItemViewModel.cs
private string _favicon;
public string Favicon
{
get
{
return _favicon;
}
set
{
if (value != _favicon)
{
_favicon = value;
NotifyPropertyChanged("Favicon");
}
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
NotifyPropertyChanged("Name");
}
}
}
private string _address;
public string Address
{
get
{
return _address;
}
set
{
if (value != _address)
{
_address = value;
NotifyPropertyChanged("Address");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
..and this is where and how I am saving each item (which should have three properties listed in the ItemViewModel
void addToFavorites_Click(object sender, EventArgs e)
{
var favoriteItem =
new ItemViewModel{
Favicon = "",
Name = "",
Address = TheBrowser.currentUrl() };
Settings.FavoritesList.Value.Add(favoriteItem);
}
Where FavoritesList is populated using an ItemViewModel containing 3 objects. The list is being populated correctly because during debugging I can see the entities in FavoritesList, but I am having an issue calling these entities in the view model to show up in my ListBox in the view?
I believe I am binding incorrectly but I'm not sure how to fix this?
In your XAML you bind to paths Name and Address do you have these 2 properties defined in your ItemViewModel?
Update after reading your code properly:
You are not updating the datatemplate of the Items of the Listbox. This is what you need to do:
<ListBox x:Name="FavoritesListBox" ItemsSource="{Binding FavoriteItems}" SelectionChanged="FavoritesListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="12,0,12,0">
<Image x:Name="favicon" Source="{Binding Favicon}" Width="50" Height="50"/>
<StackPanel>
<TextBlock x:Name="favoritesName" Text="{Binding Name}" FontSize="{StaticResource PhoneFontSizeExtraLarge}"/>
<TextBlock x:Name="favoritesAddress" Text="{Binding Address}" Margin="12,0,0,0"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In addition to setting your DataContext to your viewmodel, (as mentioned in the comment linking to Creating ContextBinding XAML) , you also need to have your view model implement INotifyPropertyChanged (including ItemViewModel, which you don't show in your question)

Categories