3

我尝试简单地将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>

代码:

答案

private ObservableCollection<PrawoJazdyDataAnswer> _answers = 
    new ObservableCollection<PrawoJazdyDataAnswer>();
public ObservableCollection<PrawoJazdyDataAnswer> Answers 
{ 
    get 
    { 
       return this._answers; 
    }  
}    

单项(答案)

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));
    }
}

转换器(有时似乎需要,而其他则不需要......,我尝试了来自不同教程/示例的 ~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;
    }

在此先感谢,并为我的英语感到抱歉(仍在学习)。

@edit 感谢您的快速回复。

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

<Button Click="spr" >Sprawdź</Button>
<TextBlock Text="{Binding Answers[0].IsSelected, Mode=TwoWay}" > </TextBlock> 

它在其他控件部分(在列表框上方,但在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;
    }

正如我所写,当我从代码端更改数据时,它正在更改元素的内容,而不是ListBoxItem. 如果我只是选择它,ListBox它本身不会改变数据。TextBlockListBox

@edit2 修正错别字...

4

2 回答 2

10

要更改 的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>

由于绑定模式是TwoWay,选择和取消选择ListBoxItem's 会动态更改项目的内容以显示Trueor False

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

ListBoxItem作为ItemTemplate

在此处输入图像描述

TextBlock作为ItemTemplate

在此处输入图像描述

编辑

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

于 2012-09-18T13:05:19.337 回答
1

不要绑定到 ListBoxItem 上的 IsSelected。ListBox 获得了 SelectedItem 或 SelectedItems 属性,您应该在其中传递要选择的项目,即通过绑定。在模型中设置 IsSelected 属性不是一个好主意。最好在 ViewModel 中设置 SelectedItem 通知属性。

于 2012-09-18T07:19:52.160 回答