Reputation: 25
My goal was to make a list of selectable shows where the user can pick one, then edit data about it in the right panel.
I have an ObservableCollection
that is bound to a ListView
. The test Show
s appear correctly. I also have a Show SelectedShow
that is bound using Mode.TwoWay
. When I select a different Show
in the ListView
, I receive the corresponding debug statement.
The TextBlock
's Text
does not change when I click different Show
s in the ListView
.
Any ideas?
MainPage.xaml:
<Page
x:Class="PlexHelper.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PlexHelper"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="6*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<TextBox HorizontalAlignment="Stretch" Text="" PlaceholderText="Search shows..."/>
<ListView ItemsSource="{x:Bind Shows}" SelectedItem="{x:Bind SelectedShow, Mode=TwoWay}" SelectionChanged="OnSelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Show">
<TextBlock Text="{x:Bind Name, Mode=OneWay}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<TextBlock Grid.Column="1" FontSize="50" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{x:Bind SelectedShow.Name, Mode=OneWay}"></TextBlock>
</Grid>
</Page>
MainPage.xaml.cs:
using System.Collections.ObjectModel;
using System.Diagnostics;
using Windows.UI.Xaml.Controls;
namespace PlexHelper
{
public sealed partial class MainPage : Page
{
public ObservableCollection<Show> Shows { get; } = new ObservableCollection<Show>();
public Show SelectedShow { get; set; }
public MainPage()
{
this.InitializeComponent();
Shows.Add(new Show("Show 1"));
Shows.Add(new Show("Show 2"));
Shows.Add(new Show("Show 3"));
SelectedShow = Shows[0];
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine("now selected: " + SelectedShow.Name);
}
}
}
Show.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace PlexHelper
{
public class Show : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Show(string name = "Default Show Name")
{
Name = name;
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 2
Views: 975
Reputation: 1595
You need to raise PropteryChanged event for SelectedShow as well in order to reflect it on UI.
Your MainPlage
should look like this:
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public ObservableCollection<Show> Shows { get; } = new ObservableCollection<Show>();
private Show _selectedShow;
public Show SelectedShow
{
get => _selectedShow;
set
{
if (_selectedShow != value)
{
_selectedShow = value;
OnPropertyChanged();
}
}
}
public MainPage()
{
this.InitializeComponent();
Shows.Add(new Show("Show 1"));
Shows.Add(new Show("Show 2"));
Shows.Add(new Show("Show 3"));
SelectedShow = Shows[0];
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine("now selected: " + SelectedShow.Name);
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
I would better recommend creating a ViewModel which contains the list of Shows along with the SelectedShow and Implement INotifyPropertyChanged in that VM.
Upvotes: 1