WPF View not binding unless I switch view before - c#

I'm trying to dev a WPF app which displays 3 views that we can switch using a side menu.
The first View displays articles. I've tried this view in another project on its own and it works just fine.
My issue:
The problem is that when I use it in my navigation (with the exact same code) the Images or Titles won't appear unless I click on another view first then click back.
Here's my current code:
Model: (Article)
public class Article : INotifyPropertyChanged
{
int id;
string title;
string link;
BitmapImage image;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Article(int id, string title, string link, BitmapImage image)
{
Id = id;
Title = title;
Link = link;
Image = image;
}
public int Id
{
get => id;
set { if (value != id) { id = value; NotifyPropertyChanged(); } }
}
public string Title
{
get => title;
set { if (value != title) { title = value; NotifyPropertyChanged(); } }
}
public string Link
{
get => link;
set { if (value != link) { link = value; NotifyPropertyChanged(); } }
}
public BitmapImage Image
{
get => image;
set { if (value != image) { image = value; NotifyPropertyChanged(); } }
}
}
ViewModel: (ArticlesViewModel)
public class ArticlesViewModel : INotifyPropertyChanged
{
Article[] articles;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public AccueilViewModel()
{
loadArticle();
}
public Article[] Articles
{
get => articles;
set { if (value != articles) { articles = value; NotifyPropertyChanged(); } }
}
private async void loadArticle()
{
var client = new WordPressClient(App.WordpressLink);
try
{
var asychArticles = GetArticles(client);
await asychArticles;
var articles = asychArticles.Result;
int i = 0;
int a;
foreach (WordPressPCL.Models.Post p in articles)
{
a = p.FeaturedMedia.Value;
var media = GetMedia(client, a);
await media;
BitmapImage bimage = App.getImage(media.Result.SourceUrl);
articleImg[i].Source = bimage;
articleTitle[i].Content = p.Title.Rendered.ToUpper();
articleLink[i] = p.Link;
i++;
if (i == 4) break;
}
}
catch (System.Net.Http.HttpRequestException e)
{
}
}
static async Task<IEnumerable<WordPressPCL.Models.Post>> GetArticles(WordPressClient client)
{
var posts = await client.Posts.GetAll();
return posts;
}
static async Task<WordPressPCL.Models.MediaItem> GetMedia(WordPressClient client, int number)
{
var media = await client.Media.GetByID(number);
return media;
}
}
View: (ArticlesView)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Grid Name="Article1" Grid.Row="0" Margin="10,10,10,10" DataContext="{Binding Articles[0]}">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Name="Image1" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
<Button Name="Titre1" Grid.Row="1" Content="{Binding Title}"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Name="Article2" Grid.Column="0" Margin="10,10,10,10" DataContext="{Binding Articles[1]}">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Name="Image2" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
<Button Name="Titre2" Grid.Row="1" Content="{Binding Title}"/>
</Grid>
<Grid Name="Article3" Grid.Column="1" Margin="10,10,10,10" DataContext="{Binding Articles[2]}">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Name="Image3" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
<Button Name="Titre3" Grid.Row="1" Content="{Binding Title}"/>
</Grid>
<Grid Name="Article4" Grid.Column="2" Margin="10,10,10,10" DataContext="{Binding Articles[3]}">
<Grid.RowDefinitions>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image Name="Image4" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
<Button Name="Titre4" Grid.Row="1" Content="{Binding Title}"/>
</Grid>
</Grid>
</Grid>
MainWindow.xaml:
<Window.Resources>
<DataTemplate x:Name="ArticlesViewTemplate" DataType="{x:Type viewmodels:ArticlesViewModel}">
<views:ArticlesView DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Name="Feature2ViewTemplate" DataType="{x:Type viewmodels:Feature2ViewModel}">
<views:Feature2View DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Name="Feature3ViewTemplate" DataType="{x:Type viewmodels:Feature3ViewModel}">
<views:Feature3View DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel Grid.Row="1" VerticalAlignment="Top" Margin="20,20,20,0">
<Button Content="Articles" Click="F1Button_Click"/>
<Button Content="F2" Click="F2Button_Click"/>
<Button Content="F3" Click="F3Button_Click"/>
</StackPanel>
</Grid>
<ContentControl Grid.Column="1" Content="{Binding}"/>
</Grid>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
ArticlesViewModel avm;
Feature2ViewModel f2vm;
Feature3ViewModel f3vm;
public MainWindow()
{
InitializeComponent();
}
private void F1Button_Click(object sender, RoutedEventArgs e)
{
if (avm == null) avm = new AccueilViewModel();
DataContext = avm;
}
private void F2Button_Click(object sender, RoutedEventArgs e)
{
if (f2vm == null) f2vm = new CatalogueViewModel();
DataContext = f2vm;
}
private void F3Button_Click(object sender, RoutedEventArgs e)
{
if (f3vm == null) f3vm = new MesFormationsViewModel();
DataContext = f3vm;
}
}
To sum up:
Click on Articles -> Nothing is displayed
Click on F2 then Articles -> Nothing is displayed
Click on Articles then F2 then Articles -> Images and Titles correctly displayed!
Any ideas on where the problem might be coming from? Thank you.

So the problem seemed to be coming from the fact that I was using an array. At the start the DataContext was null so the images and titles even though they were loaded in the modelview were not displayed on the view.
The problem was fixed by using an ObservableCollection instead of the array. If I understood correctly, NotifyPropertyChanged() is apparently not notifying the view when the array is at first null.(?)

Related

How can I use 2 data bindings for an ItemSource Data Template in WPF App

I have a counter which increments depending on a foreach Loop from:
public partial class UserControlCounter : UserControl, INotifyPropertyChanged
{
private int _scanStatusCounter;
public int ScanStatusCounter
{
get { return _scanStatusCounter; }
set { _scanStatusCounter = value; NotifyPropertyChanged(); }
}
public UserControlCounter()
{
InitializeComponent();
DataContext = this;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(getAll);
scanStatus.Text = "Persons " + ScanStatusCounter.ToString();
}
private async void getAll()
{
//grab data and iterate it
string[] string_array = new string[] { "a", "b", "c", "d", "e" }; // type = System.String[]
foreach (var i in string_array)
{
ScanStatusCounter++;
await Task.Delay(100);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
and the Xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Grid.Column="0" Name="myListBox" Height="40" ></ListBox>
<TextBlock Grid.Row="0" Grid.Column="1" Name="scanStatus" Height="40" Text="{Binding Path=ScanStatusCounter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
<Button Grid.Row="0" Grid.Column="2" Click="Button_Click" Height="40">Click Me</Button>
</Grid>
That works fine and increments "live", but my problem is that I need to get that now running inside a more complex Data Template.
I've tried to inject the Counter onClick with:
private async void Button_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var contentPresenter = (btn.TemplatedParent as ContentPresenter);
var ppStatusCounter = contentPresenter.ContentTemplate.FindName("scanStatus", contentPresenter) as TextBlock;
ppStatusCounter.Text = "Entrys found: " + ScanStatusCounter.ToString();
}
But then I get the Value only onClick not like a live incrementing Counter, that's my Data Template:
<UserControl.Resources>
<c1:NameList x:Key="NameListData"/>
<DataTemplate x:Key="NameItemTemplate">
<Grid Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Domaine"/>
<TextBox Grid.Row="1" Grid.Column="0" x:Name="txtDomainName" Text="{Binding Path=DomaineName}" Margin="0,0,5,0"></TextBox>
<Button Grid.Row="1" Grid.Column="1" Width="100" Height="30" Margin="5,5,5,5" x:Name="btnNames" Click="Button_Click" Content="Start Scan" />
<Grid Grid.Column="2" Grid.Row="1" Height="20">
<ProgressBar x:Name="pbStatus" Height="20" Width="100" Minimum="0" Maximum="100" Visibility="Hidden"/>
<TextBlock x:Name="pbStatusText" HorizontalAlignment="Center" VerticalAlignment="Center" Text="Scanning" Visibility="Hidden"/>
</Grid>
<TextBlock Grid.Column="3" Grid.Row="1" Name="scanStatus" Text="{Binding Path=ScanStatusCounter, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="top">
<StackPanel Orientation="Horizontal" Margin="0,20,0,0">
<ListBox x:Name="lstDomainNames"
Margin="5,5,5,5"
ItemsSource="{Binding Source={StaticResource NameListData}}"
ItemTemplate="{StaticResource NameItemTemplate}"
IsSynchronizedWithCurrentItem="True"/>
</StackPanel>
</StackPanel>
</Grid>
that's my Data Source Class, not much there:
public partial class NameList : ObservableCollection<SetCredentials>
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public NameList() : base()
{
using var forest = Forest.GetCurrentForest();
Forest currentForest = Forest.GetCurrentForest();
DomainCollection domains = currentForest.Domains;
foreach (Domain objDomain in domains)
{
Add(new SetCredentials(objDomain.ToString()));
}
}
}
public class SetCredentials
{
private string domainName;
public SetCredentials(string domain)
{
this.domainName = domain;
}
public string DomaineName
{
get { return domainName; }
set { domainName = value; }
}
}
Do I have to add a second Data Binding source to my ItemSource or do I need another approach for this, for example in my TextBox Binding?

Get index of data binding from ItemsControl

Is there any way to get the index of the data which is binded to the ItemsControl, when a button is clicked?
<ItemsControl x:Name="ic_schranke" DataContext="{Binding Schranke}" >
<ItemsControl.ItemTemplate>
<DataTemplate >
<Button Height="80" x:Name="btn_open" Click="btn_open_Click" HorizontalAlignment="Stretch" Style="{StaticResource TransparentStyle}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="30*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Rectangle x:Name="rect" Grid.ColumnSpan="3" Grid.Row="1" Opacity="0.65" Grid.Column="0" Fill="#FFCEEAFF"/>
<Border CornerRadius="25" Height="50" Width="50" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="1">
<Border.Background>
<ImageBrush ImageSource="/Assets/schranken.jpg" />
</Border.Background>
</Border>
<TextBlock Name="schranken_name" Grid.Column="1" Grid.Row="1" Text="{Binding name}" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="ExtraLight" Foreground="Black" />
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Here is the sample data which is binded to the IC:
List<Schranke> elements;
public UserPage()
{
this.InitializeComponent();
elements = new List<Schranke>();
for (var i = 1; i < 15; i++)
elements.Add(new Schranke() { name = $"Schranke NR:{i}" });
this.ic_schranke.ItemsSource = elements;
}
And here is the code in the button click event:
private async void btn_open_Click(object sender, RoutedEventArgs e)
{
Grid grid = (sender as Button).Content as Grid;
//Debug.WriteLine($"content {tb.Text} clicked");
var tmp_background = grid.Background;
grid.Background = new SolidColorBrush(new Windows.UI.Color() { A = 255, R = 78, G = 170, B = 44 });
VibrationDevice testVibrationDevice = VibrationDevice.GetDefault();
testVibrationDevice.Vibrate(System.TimeSpan.FromMilliseconds(150));
await Task.Delay(3000);
grid.Background = tmp_background;
}
Maybe something along the lines of this:
the presenter - put this in the data context
public class SchrankePresenter : INotifyPropertyChanged
{
private List<Schranke> _elements;
public List<Schranke> Elements
{
get { return _elements; }
set
{
_elements = value;
OnPropertyChanged("Elements");
}
}
public ICommand ClickCommand { get; set; }
private void OnPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
public SchrankePresenter()
{
var elements = new List<Schranke>();
for (var i = 1; i < 15; i++)
elements.Add(new Schranke() { Name = $"Schranke NR:{i}" });
Elements = elements;
ClickCommand = new DelegateCommand(ClickAction);
}
public void ClickAction(Schranke item)
{
VibrationDevice.GetDefault().Vibrate(TimeSpan.FromMilliseconds(150));
}
}
public class Schranke
{
public string Name { get; set; }
}
the template:
<ListView ItemsSource="{Binding Elements}">
<ListView.ItemTemplate>
<DataTemplate>
<Button Height="80"
HorizontalAlignment="Stretch"
Command="{Binding ClickCommand}"
Style="{StaticResource TransparentStyle}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="30*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Rectangle x:Name="rect"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Fill="#FFCEEAFF"
Opacity="0.65" />
<Border Grid.Row="1"
Grid.Column="0"
Width="50"
Height="50"
HorizontalAlignment="Center"
CornerRadius="25">
<Border.Background>
<ImageBrush ImageSource="/Assets/schranken.jpg" />
</Border.Background>
</Border>
<TextBlock Name="schranken_name"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontWeight="ExtraLight"
Foreground="Black"
Text="{Binding Name}" />
</Grid>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
you can do the background animation using a storyboard/visualstate
EDIT : regarding the DelegateCommand, it's a simple implementation I use for my WPF apps -
internal class DelegateCommand<T> : ICommand
{
private Action<T> _clickAction;
public DelegateCommand(Action<T> clickAction)
{
_clickAction = clickAction;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_clickAction((T)parameter);
}
}

WPF: ObservableCollection Memory leak

[I'm sorry for my bad English]
In my MainWindow I have some ContentControl and I set his Content to some view called SimpleView. If that SimpleView has ListBox bounded to Collection, The view is alive even if I remove the SimpleView.
All my viewmodels are Implementing INotifyPropertyChanged.
This is my code:
MainWindow.xaml
<Window x:Class="WpfMemory.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Set view" Click="SetView" />
<Button Content="Clear view" Click="ClearView" />
</StackPanel>
<ContentControl x:Name="ViewContainer" Grid.Row="1" Margin="4" />
</Grid>
</Window>
In code behind
private void SetView(object sender, RoutedEventArgs e)
{
var simpleViewModel = new ViewModels.SimpleViewModel();
var simpleview = new Views.SimpleView() { DataContext = simpleViewModel };
ViewContainer.Content = simpleview;
}
private void ClearView(object sender, RoutedEventArgs e)
{
ViewContainer.Content = null;
System.GC.Collect();
}
SampleView.xaml
<UserControl x:Class="WpfMemory.Views.SimpleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition MinWidth="60"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="SomeText" />
<TextBox Text="{Binding SomeText}" Grid.Column="1"/>
<TextBlock Text="Large data" Grid.Row="1"/>
<ListBox ItemsSource="{Binding LargeData,Mode=OneTime}"
Grid.Row="2" Grid.Column="1"
DisplayMemberPath="Name" />
</Grid>
</UserControl>
View models
public sealed class SimpleViewModel : ViewModelBase
{
public SimpleViewModel()
{
var items = Enumerable.Range(1, 10000)
.Select(x => new SimpleItem()
{
Id = x,
Name = "Item " + x
})
.ToArray();
LargeData = new ObservableCollection<SimpleItem>(items);
}
public string SomeText{ get; set; } = "yehudah";
ObservableCollection<SimpleItem> largeData;
public ObservableCollection<SimpleItem> LargeData
{
get { return largeData; }
set { SetProperty(ref largeData, value); }
}
}
public sealed class SimpleItem : ViewModelBase
{
public int Id { get; set; }
public string Name { get; set; }
}
I run the application and Click on SetView and then on ClearView.
Now, in vs diagnostic tools I click on "Take snapshot" And this is the result:
Thanks for any help.
I think you should reset simpleview.DataContext when content control is unloaded.
You can do
simpleview.Unloaded += (_, __) => simpleview.DataContext = null;
when SetView.

How to handle item highlight in ListBox when using more than one ListBox using wpf c#

I am using more than one customise ListBox in my application.
I want that when I click on item in one of the ListBox then highlight in other ListBox should be remove .Means I want to select item in one of the ListBox at a time.I provide sample code here
MainWindow.xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<view:ListBox_UserControl x:Name="Control_1"/>
</Grid>
<Grid Grid.Row="1">
<view:ListBox_UserControl x:Name="Control_2"/>
</Grid>
<Grid Grid.Row="2">
<view:ListBox_UserControl x:Name="Control_3"/>
</Grid>
</Grid>
<Grid Grid.Column="1" Background="Aqua">
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Control_1.ListBox_ItemSource = List_1;
Control_2.ListBox_ItemSource = List_1;
Control_3.ListBox_ItemSource = List_1;
}
List<string> List_1 = new List<string>()
{
"Item_1",
"Item_2",
"Item_3",
"Item_4",
"Item_5"
};
}
ListBox_UserControl.xaml
<Grid>
<ListBox Name="ListBox_1">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ListBox_UserControl.xaml.cs
public partial class ListBox_UserControl : UserControl
{
protected event MouseButtonEventHandler TextBlock_Click;
public ListBox_UserControl()
{
InitializeComponent();
}
public List<string> ListBox_ItemSource
{
set
{
ListBox_1.ItemsSource = value;
}
}
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MouseButtonEventHandler handler = TextBlock_Click;
if(handler!=null)
{
handler(sender, e);
}
}
}

WP7 - Binding class to grid

I have grid like this:
<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="CurrentPoints" Grid.Row="1" Grid.Column="0"
Text="{Binding CurrentPoints}" Width="100" Height="100" Foreground="Red">
</TextBlock>
<TextBlock x:Name="PointsLeft" Grid.Row="1" Grid.Column="1"
Text="{Binding AllPoints}" Width="100" Height="100" Foreground="Red" />
<TextBlock x:Name="AllPoints" Grid.Row="1" Grid.Column="2"
Text="{Binding EndPoints}" Grid.ColumnSpan="1"/>
</Grid>
Code for page like this:
Counter pocitadlo = new Counter(200);
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
LayoutRoot.DataContext = pocitadlo;
}
And this is my counter class:
class Counter : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _currentPoints;
public int CurrentPoints
{
get
{
return _currentPoints;
}
set
{
this._currentPoints = value;
onPropertyChanged(this, "CurrentPoints");
}
}
private int _allPoints;
public int AllPoints
{
get
{
return _allPoints;
}
set
{
this._allPoints = value;
onPropertyChanged(this, "AllPoints");
}
}
private int _endPoints;
public int EndPoints
{
get
{
return _endPoints;
}
set
{
this._endPoints = value;
onPropertyChanged(this, "EndPoints");
}
}
public Counter(int endPoints)
{
this._allPoints = 0;
this._currentPoints = 0;
this._endPoints = endPoints;
}
private void onPropertyChanged(object sender, string property)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(sender, new PropertyChangedEventArgs(property));
}
}
}
Why isnĀ“t binding working? What I am missing? Thanks

Categories