标签控件未选择可观察集合WPF中的第一项

时间:2020-05-23 23:25:43

标签: c# wpf xaml

我注意到,将TabControl属性绑定到ItemsSource的{​​{1}}不会选择集合中的第一项:

  1. ObservableCollection的计数为0(未显示标签项)时加载TabControl
  2. ObservableCollection添加一个项目,观察到一个ObservableCollection现在存在但未被选中

如果您在TabItem首次成为焦点之前向ObservableCollection添加一个项目,则TabControl中的一个项目的{已选择{1}}。似乎只有当分页计数达到0然后又增加时,它似乎失去了选择第一项的能力。

这似乎是设计使然。有什么办法可以解决这个问题?

我在XAML中具有以下tabcontrol定义,如下所示:

TabControl

2 个答案:

答案 0 :(得分:1)

如果您将tabControl命名为TabControl,则可以在代码背后订阅其项集合中的更改:

<TabControl ItemsSource="{Binding Sels}" x:Name="tabControl" />
tabControl.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;

,然后如果未选择任何选项卡,则可以强制其选择第一个选项卡:

private async void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e) {
    await Task.Yield();
    if (tabControl.SelectedIndex == -1) {
        if (tabControl.Items.Count > 0) {
            tabControl.SelectedIndex = 0;
        }
    }
}

需要调用await Task.Yield(),以使WPF在更改其TabControl属性之前完成内部SelectedIndex的更新。


要更加花哨

您可以将其放在attached DependencyProperty中,并且很好拥有更干净的XAML,并且没有多余的代码:

<TabControl ItemsSource="{Binding Sels}" local:AutoSelect.AutoSelectFirstTab="true"/>

这是相同的行为,但使用附加了DependencyProperty的WPF进行包装:

public static class AutoSelect {
    public static readonly DependencyProperty AutoSelectFirstTabProperty = DependencyProperty.RegisterAttached(
        "AutoSelectFirstTab",
        typeof(bool),
        typeof(AutoSelect),
        new PropertyMetadata(false, AutoSelectFirstTabChanged));

    public static bool GetAutoSelectFirstTab(TabControl obj) => (bool)obj.GetValue(AutoSelectFirstTabProperty);
    public static void SetAutoSelectFirstTab(TabControl obj, bool value) => obj.SetValue(AutoSelectFirstTabProperty, value);

    private static void AutoSelectFirstTabChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var tabControl = (TabControl)d;
        tabControl.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
        async void ItemContainerGenerator_ItemsChanged(object _1, ItemsChangedEventArgs _2) {
            await Task.Yield();
            if (GetAutoSelectFirstTab(tabControl)) {
                if (tabControl.SelectedIndex == -1) {
                    if (tabControl.Items.Count > 0) {
                        tabControl.SelectedIndex = 0;
                    }
                }
            }
        }
    }
}

答案 1 :(得分:0)

除了Corentin的回答,我只想补充一点,根据您填充 public function doWaterMark() { $currentFile = $this->file; //$currentFile = put here your file; $Username = "UserName"; $this->pdf = new FPDI(); $pagecount = $this->pdf->setSourceFile($currentFile); for ($i = 1; $i <= $pagecount; $i++) { $this->pdf->addPage(); //<- moved from outside loop $tplidx = $this->pdf->importPage($i); $this->pdf->useTemplate($tplidx, 10, 10, 100); // now write some text above the imported page $this->pdf->SetFont('Arial', 'I', 40); $this->pdf->SetTextColor(255, 0, 0); $this->pdf->SetXY(25, 135); $this->_rotate(55); $this->pdf->Write(0, $Username); $this->_rotate(0); //<-added } $this->pdf->Output('New File Name', 'F'); } 的方式,您也可以将第一项分配给视图模型中的指定属性。

在与您非常相似的情况下,我以代码方式处理从MEF容器收集的导出插件。完成此操作后,我只需在视图模型中更新属性ObservableCollection,然后在XAML中对SelectedPlugin的{​​{1}}进行 TwoWay 绑定至此属性

这很好用,并且完全可以满足您的用例。