C# WPF-如何在MouseUp事件中停止TabControl更改索引?

C# WPF-如何在MouseUp事件中停止TabControl更改索引?,c#,wpf,C#,Wpf,我有一个TabControl,其中包含多个TabItems的ItemsSource,还有一个附加的TabItem,用于将新的TabItems添加到此列表中。负责添加项的选项卡item侦听MouseUp事件。 问题是,添加项目后,我更新SelectedIndex,但SelectedIndex会更改为我单击的元素 XAML的一部分: <TabControl ItemsSource="{Binding Tabs}" SelectedIndex="{Binding SelectedIndex}"&

我有一个TabControl,其中包含多个TabItems的ItemsSource,还有一个附加的TabItem,用于将新的TabItems添加到此列表中。负责添加项的选项卡item侦听MouseUp事件。 问题是,添加项目后,我更新SelectedIndex,但SelectedIndex会更改为我单击的元素

XAML的一部分:

<TabControl ItemsSource="{Binding Tabs}" SelectedIndex="{Binding SelectedIndex}">

我的代码:

public ObservableCollection<TabItem> Tabs { get; set; }
public int SelectedIndex { get; set; }

private void Tab_add_MouseUp(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
    int count = Tabs.Count;
    TabItem tabItem = new TabItemDepartment("Header #x");
    Tabs.Insert(count - 1, tabItem);
    SelectedIndex = count - 2;
}
publicobservableCollection选项卡{get;set;}
public int SelectedIndex{get;set;}
私有无效选项卡添加鼠标(对象发送器,鼠标按钮ventargs e)
{
e、 已处理=正确;
int count=Tabs.count;
TabItem TabItem=新的TabItemDepartment(“标题#x”);
Tabs.插入(计数-1,tabItem);
SelectedIndex=计数-2;
}
编辑:基于答案的最终代码(仅相关部分):

public class CalendarViewModel : INotifyPropertyChanged
{
    public ObservableCollection<TabItem> Tabs { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    private int _SelectedIndex;
    public int SelectedIndex
    {
        get
        {
            return _SelectedIndex;
        }
        set
        {
            _SelectedIndex = value;
            NotifyPropertyChanged(nameof(SelectedIndex));
        }
    }

    private void Tab_add_MouseDown(object sender, MouseButtonEventArgs e)
    {
        TabItem tabItem = new TabItemDepartment("Header #x");
        Tabs.Insert(Tabs.Count - 1, tabItem);
        SelectedIndex = Tabs.Count - 2;
        e.Handled = true;
    }

    protected void NotifyPropertyChanged(string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
公共类CalendarViewModel:INotifyPropertyChanged
{
公共ObservableCollection选项卡{get;set;}
公共事件属性更改事件处理程序属性更改;
私有int_选择的索引;
公共整数选择索引
{
得到
{
返回所选的索引;
}
设置
{
_SelectedIndex=值;
NotifyPropertyChanged(名称(SelectedIndex));
}
}
私有无效选项卡添加鼠标向下(对象发送器,鼠标按钮ventargs e)
{
TabItem TabItem=新的TabItemDepartment(“标题#x”);
Tabs.Insert(Tabs.Count-1,tabItem);
SelectedIndex=制表符。计数-2;
e、 已处理=正确;
}
受保护的void NotifyPropertyChanged(字符串propertyName=null)
{
this.PropertyChanged?.Invoke(this,newpropertychangedeventargs(propertyName));
}
}

您需要使用
DependencyProperty
INotifyPropertyChanged
,因为绑定引擎不知道
SelectedIndex
属性的更改

public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register(
    "SelectedIndex",
    typeof(int),
    typeof(WhateverYourClassNameIs));

public int SelectedIndex
{
    get { return (int)GetValue(SelectedIndexProperty); }
    set { SetValue(SelectedIndexProperty, value); }
}

或者,您可以使此类实现
INotifyPropertyChanged
,但通常对于已经从
FrameworkElement
(带UI的类)派生的类,
DependencyProperty
将是首选。

这里有两个问题:

  • SelectedIndex
    需要是
    dependencProperty
    或者定义了
    SelectedIndex
    的类需要实现
    inotifPropertyChanged
  • 试试这个:

    public int SelectedIndex
    {
        get { return (int)GetValue(SelectedIndexProperty); }
        set { SetValue(SelectedIndexProperty, value); }
    }
    
    public static readonly DependencyProperty SelectedIndexProperty =
        DependencyProperty.Register("SelectedIndex", typeof(int), typeof(YOURCLASS), new PropertyMetadata(0));
    
    private void Tab_add_MouseUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        // Only add if the user clicks on the last items.
        if (this.SelectedIndex == this.Tabs.Count - 1)
        {
            TabItem tabItem = new TabItemDepartment("Header #x");
            this.Tabs.Insert(this.Tabs.Count - 1, tabItem);
            // The Count has changed at this point so make sure we check the collection again.
            this.SelectedIndex = this.Tabs.Count - 2;
        }
    }
    
  • 您在鼠标上升事件中的逻辑是错误的。我假设您只想在单击最后一项时添加选项卡?此外,您不能使用本地计数变量,因为一旦添加新选项卡,集合中的项目数将发生变化
  • 试试这个:

    public int SelectedIndex
    {
        get { return (int)GetValue(SelectedIndexProperty); }
        set { SetValue(SelectedIndexProperty, value); }
    }
    
    public static readonly DependencyProperty SelectedIndexProperty =
        DependencyProperty.Register("SelectedIndex", typeof(int), typeof(YOURCLASS), new PropertyMetadata(0));
    
    private void Tab_add_MouseUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        // Only add if the user clicks on the last items.
        if (this.SelectedIndex == this.Tabs.Count - 1)
        {
            TabItem tabItem = new TabItemDepartment("Header #x");
            this.Tabs.Insert(this.Tabs.Count - 1, tabItem);
            // The Count has changed at this point so make sure we check the collection again.
            this.SelectedIndex = this.Tabs.Count - 2;
        }
    }
    

    尝试在preview mousedown事件中执行此操作,如果
    e.Handled
    阻止事件向下路由,则它应该可以工作。这可以工作,但不会更改所选的索引。因此,当我单击add选项卡时,索引保持不变。因此,我必须将我的ViewModel更改为
    公共类CalendarViewModel:DependencyObject
    (这是定义和注册eventhandler的地方),并将
    typeof
    更改为
    typeof(CalendarViewModel)
    ?我尝试了这个,但它仍然无法更新索引。如果您已经在使用MVVM,请使用INotifyPropertyChanged。网上有很多这样的例子@JohannesRight,我在重新编写代码,但忘记更改计数的代码-因为它一开始就不起作用,所以我忽略了这个错误。我尝试使用DependencyProperty,但它不起作用,所以我选择了
    INotifyPropertyChanged
    ,它确实起作用。