【问题标题】:ListBox Selected Items are reset each time I switch tabs in may TabControl每次我在 TabControl 中切换选项卡时,ListBox Selected Items 都会重置
【发布时间】:2017-01-17 08:35:27
【问题描述】:

我有以下 TabControl:

<TabControl Name="tabControl" Grid.Row="0" MinWidth="270" HorizontalAlignment="Stretch" ItemsSource="{Binding Counters}" ContentTemplate="{StaticResource templateForTheContent}"
        ItemTemplate="{StaticResource templateForTheHeader}">
</TabControl>

它使用这个 DataTemplate:

<Window.Resources>

            <DataTemplate x:Key="templateForTheContent" >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*"/>
                    <RowDefinition  Height="Auto"/>
                </Grid.RowDefinitions>
                <ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" 
                         ItemsSource="{Binding}"
                         SelectionMode="Multiple"
                             BorderThickness="1" BorderBrush="#FF8B8B8B" SelectionChanged="ListBox_SelectionChanged_1">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock>
                                <Run Text="{Binding CounterName, Mode=OneWay}" />
                                <Run Text="{Binding InstanceName, Mode=OneWay}" />
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1">
                    <TextBlock Text="SELECT ALL"/>
                </Button>
                <Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1">
                    <TextBlock Text="UNSELECT ALL"/>
                </Button>
            </Grid>
        </DataTemplate>

            <DataTemplate x:Key="templateForTheHeader" >
                <TextBlock Text="{Binding CategoryName}"/>
            </DataTemplate>

        </Window.Resources>

它按预期工作,绑定工作良好,如果不存在此问题,一切都会很好: 每次我在 TabControl 中切换一个选项卡时,我之前的选项卡中的 ListBox 的选定项目都会被重置 - 所以当我返回该选项卡时 - 没有选择任何内容。

如何解决这个问题?

//编辑 这是我的 ListBox_SelectionChanged_1 方法:

private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
    System.Windows.Controls.ListBox listBoxTemp = sender as System.Windows.Controls.ListBox;
    PerformanceCounter counterTemp = (PerformanceCounter)listBoxTemp.Items[0];

    if (!appData.SelectedCounters.ContainsKey(counterTemp.CategoryName))
        appData.SelectedCounters.Add(counterTemp.CategoryName, new List<PerformanceCounter>());

    appData.SelectedCounters[counterTemp.CategoryName].Clear();

    foreach (PerformanceCounter counter in listBoxTemp.SelectedItems)
    {
        appData.SelectedCounters[counterTemp.CategoryName].Add(counter);
    }

}

ListBox 绑定到 Counters,也就是 Observable Collection:

public ObservableCollection<ObservableCollection<PerformanceCounter>> Counters
{
    get { return _Counters; }
}
ObservableCollection<ObservableCollection<PerformanceCounter>> _Counters = new ObservableCollection<ObservableCollection<PerformanceCounter>>();

【问题讨论】:

  • 如果我可以在当前选定的选项卡中访问 ListBox,我将能够处理这个问题。怎么做?我试过 IEnumerable listBoxList = tabControl.FindChildren();,但它是空的(虽然有一个 ListBox)
  • 将 ListBox 绑定到集合后,您将无法从后面的代码中的 Items 访问 IsSelected 属性。您必须通过与 ViewModel 的相应属性绑定来管理它
  • 我使用了列表框。所选项目

标签: c# wpf xaml listbox tabcontrol


【解决方案1】:

(我不熟悉 TabControls 或 WPF,但我会建议这样的解决方案:)

在字典中备份列表框的选定项目。

var selectionBackups = new Dictionary<ListBox, IEnumerable<ListBoxItem>>();

我会在ListBox_SelectionChanged_1() 中更新此字段。每当您输入 Tab 时,覆盖相关的ListBox 的选择。

void TabEnter(object sender, TabEventArgs e)
{
    ListBox lb = ... //acquire the current Listbox
    OverwriteSelection(lb, selectionBackups[lb]); //set the ListBox's selection
}

(您可能希望在恢复选择时阻止ListBox_SelectionChanged_1() 触发。可以这样做:

bool auto_select = false; //set this to true while editing selections
private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
    if(auto_select)
        return;
    ...
}

)

【讨论】:

  • 哈哈,我也有同样的想法。我正在尝试这样做,但有一个问题。这是关于这个 TabEnter 方法的。我认为在 WPF 中这是 tabControl_SelectionChanged()。所以我添加了这个事件,我想获取当前的 ListBox(就像在你的代码中一样)。我从这里使用了 FindVisualChildren 方法:Link 但它让我得到了存在于 PREVIOUS 选项卡中的 ListBox - 而不是当前选项卡。我不知道如何访问当前选定选项卡内的 ListBox。
  • hmm,EventArgs 中指定了所选 Tab 的索引吗?如果您可以在 Tab 的子项中找到 ListBox,这可能会有所帮助。
  • 是的,它有 SelectedIndex(我检查过它是正确的索引)。我还可以访问当前选定选项卡的标题 (tabControl.SelectedItem.First())。但为什么它给了我以前的 ListBox,而不是他现在的?我还查看了 ListBox 的事件,但我没有看到任何适合这种情况的事件。有 Loaded() 事件,但它仅在第一次显示 ListBox 时发生 - 以后不会。
  • 我不知道,为什么它不应该找到它。您是否使用正确的 Tab 作为 depObj 参数调用它? (tabControl.Items[e.SelectedIndex] 也许?)。事后思考:这种方法是否只撕毁实际可见的物体?如果正确的 ListBox 仍然隐藏,当 Event 被触发时,这可以解释它。
  • 我用整个窗口作为参数调用这个方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多