listbox是在DataTemplate中选择数据绑定

Kin*_*rui 2 c# data-binding xaml datatemplate wpf-controls

我尝试在我的类中IsSelected使用IsSelected字段简单地数据绑定属性.但是在我更改代码中的值之后,它不会更改属性,也不会ListBoxItem更改字段值.

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>
Run Code Online (Sandbox Code Playgroud)

码:

答案

private ObservableCollection<PrawoJazdyDataAnswer> _answers = 
    new ObservableCollection<PrawoJazdyDataAnswer>();
public ObservableCollection<PrawoJazdyDataAnswer> Answers 
{ 
    get 
    { 
       return this._answers; 
    }  
}    
Run Code Online (Sandbox Code Playgroud)

单项(答案)

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); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

FirePropertyChanged

public class NPCHelper : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void FirePropertyChanged(string prop)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}
Run Code Online (Sandbox Code Playgroud)

转换器(有时似乎需要而其他人不需要......,我尝试了来自不同教程/示例的10种方法)

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;
    }
Run Code Online (Sandbox Code Playgroud)

在此先感谢,对不起我的英语(仍在学习).

@edit感谢您的快速回复.

出于测试目的,我创建了一个按钮和文本块:

<Button Click="spr" >Sprawd?</Button>
<TextBlock Text="{Binding Answers[0].IsSelected, Mode=TwoWay}" > </TextBlock> 
Run Code Online (Sandbox Code Playgroud)

它位于其他控件部分(上面的列表框中,但是在FlipView)中单击方法

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;
    }
Run Code Online (Sandbox Code Playgroud)

正如我所写,当我从代码端更改数据时,它正在改变元素的内容,但不是外观ListBoxItem.如果我只是选择它ListBox,它不改变数据TextBlock无论是在ListBox本身.

@ edit2修复错别字...

Dyl*_*dor 8

要更改IsSelected属性ListBoxItem,需要更改ListBox.ItemContainerStyle.看这里:

<ListBox Grid.Row="1" Grid.ColumnSpan="3"
                SelectionMode="Multiple" VerticalAlignment="Center" 
                ItemsSource="{Binding Answers}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding IsSelected}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

由于绑定模式是TwoWay,选择和取消选择ListBoxItem动态更改要显示的项目的内容TrueFalse.

还要注意我是如何将其更改ListBox.ItemTemplate为a TextBlock而不是a ListBoxItem.的ItemTemplate定义的内容ListBoxItem,所以某些类型的内容的控制,通常使用.下面是不同布局的UI结构(可以使用WPF Tree Visualizer查看).

ListBoxItem作为ItemTemplate:

在此输入图像描述

TextBlock作为ItemTemplate:

在此输入图像描述

编辑

还要注意我删除了IValueConverter.由于源属性和目标属性都是bool,因此在这种情况下不需要转换器.尝试删除转换器引用以查看是否可以解决问题.