I try to simply databind IsSelected
property with IsSelected
field in my class. But after I change the value in code, it doesn't change the property, neither does clicking on ListBoxItem
change the field value.
XAML:
<FlipView ItemsSource="{Binding Source={StaticResource itemsViewSource}}" ... >
<FlipView.ItemTemplate>
<DataTemplate>
<UserControl Loaded="StartLayoutUpdates"
Unloaded="StopLayoutUpdates">
<!-- other controls -->
<ListBox Grid.Row="1" Grid.ColumnSpan="3"
SelectionMode="Multiple" VerticalAlignment="Center"
ItemsSource="{Binding Answers}">
<ListBox.Resources>
<local:LogicToText x:Key="logToText" />
</ListBox.Resources>
<!-- bind IsSelected only in one way from
code to content -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<ListBoxItem
IsSelected="{Binding IsSelected, Mode=TwoWay, Converter={StaticResource logToText}}"
Content="{Binding IsSelected, Mode=TwoWay, Converter={StaticResource logToText}}">
</ListBoxItem>
</DataTemplate>
</ItemsControl.ItemTemplate>
<!-- not working at all
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="Content"
Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.Resources>-->
</ListBox>
</UserControl>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
Code:
Answers
private ObservableCollection<PrawoJazdyDataAnswer> _answers =
new ObservableCollection<PrawoJazdyDataAnswer>();
public ObservableCollection<PrawoJazdyDataAnswer> Answers
{
get
{
return this._answers;
}
}
Single item(Answer)
public class PrawoJazdyDataAnswer : NPCHelper// PrawoJazdy.Common.BindableBase
{
public PrawoJazdyDataAnswer(String ans, bool ansb)
{
this._ans = ans;
this._isSelected = ansb;
}
public override string ToString()
{
return _isSelected.ToString(); //Only For debug purposes
//normally return _ans
}
private string _ans;
public string Ans
{
get { return this._ans; }
//set { this.SetProperty(ref this._ans, value); }
}
private bool _isSelected;
public bool IsSelected
{
get { return this._isSelected; }
set
{
_isSelected = value;
FirePropertyChanged("IsSelected");
//this.SetProperty(ref this._isSelected, value);
}
}
}
FirePropertyChanged
public class NPCHelper : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void FirePropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
Converter(which sometimes seems to be needed and others not..., I tried ~10 approaches from different tutorials/examples)
public class LogicToText : IValueConverter
{
/// <summary>
///
/// </summary>
public object Convert(object value, Type targetType,
object parameter, string language)
{
//if (value == null || (bool)value == false)
// return "False";
return value.ToString();
}
/// <summary>
///
/// </summary>
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
return value.ToString().Contains("True") ? true : false;
}
Thanks in advance, and sorry for my English(still learning).
@edit Thanks for quick reply.
For test purposes I created a button and text block:
<Button Click="spr" >Sprawdź</Button>
<TextBlock Text="{Binding Answers[0].IsSelected, Mode=TwoWay}" > </TextBlock>
It's in other controls part (above list box, but in FlipView
)
Click method
private void spr(object sender, RoutedEventArgs e)
{
var ans = ((PrawoJazdyDataQuestion)this.flipView.SelectedItem).Answers;
foreach (var item in ans)
item.IsSelected = item.IsSelected ? false : true;
}
As I wrote, when i'm changing data from code side, it is changing content of element, but not appearance of ListBoxItem
. And if I just select it on ListBox
, it doesn't change the data in TextBlock
neither in ListBox
itself.
@edit2 fixing typos...
Do not bind to IsSelected on ListBoxItem. ListBox got SelectedItem or SelectedItems property, where You should pass item(s) to be selected, i.e. by binding. Setting IsSelected property in model is not good idea. Better make SelectedItem notify property in ViewModel.
To change the
IsSelected
property of theListBoxItem
, you need to change theListBox.ItemContainerStyle
. See here:Since the binding mode is
TwoWay
, selecting and deselecting theListBoxItem
's dynamically changes the content of the items to display eitherTrue
orFalse
.Also notice how I changed the
ListBox.ItemTemplate
into aTextBlock
instead of aListBoxItem
. TheItemTemplate
defines the content of theListBoxItem
, so some type of content control is typically used. Below is the UI structure for the different layouts (this can be viewed using the WPF Tree Visualizer).ListBoxItem
as theItemTemplate
:TextBlock
as theItemTemplate
:Edit
Also note that I removed the
IValueConverter
. Since your source and target properties are bothbool
, there is no need for a converter in this case. Try removing the converter references to see if that fixes the problem.