WPF TabControl Header和Content没有更新

本文关键字:更新 Content TabControl Header WPF | 更新日期: 2023-09-27 18:06:14

设置:我有一个0…N个选项卡,每个选项卡绑定到一个类:

class MyTabItem
{
    string Text {get; set;}
    int ID {get; set;}
    ISet<MyTabContent> Contents {get; set;}
}
Class MyTabContent
{
    int ID {get; set;}
    string Subtext {get; set;}
}

每个表项类在它的集合中有许多表内容类。(整个东西都是通过NHibernate获取的)。

我已经尝试了很多东西来绑定MyTabItem的内容到每个tabcontrol项的头,以及MyTabContent的内容到每个tabcontrol项内容中的数据网格。

我可以在选项卡中显示所有内容,但是每当我更改绑定类中的属性时,UI不会更新。我试过调用InvalidateVisual,试过调度渲染事件,试过在绑定上UpdateTarget和UpdateSource(最后2个抛出异常)。我在我的视图模型中实现了INotifyPropertyChanged,甚至尝试手动使用OnPropertyChanged("MyTabItem"),但无济于事。

我真的不明白为什么当我改变绑定类的属性时我的tabcontrol内容不会更新。我尝试了2种不同的绑定策略,无论是在显示内容,但没有更新时,内容的变化。

我的XAML设置是:

<TabControl>
  <TabControl.ItemTemplate>
    <DataTemplate DataType="models:MyTabItem">
      <TextBlock Text="{Binding Text}" />
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabControl.ContentTemplate>
    <DataTemplate DataType="models:MyTabItem">
      <DataGrid ItemsSource="{Binding Contents}">
        <DataGrid.Columns>
          <DataGridTextColumn Binding="{Binding Path=Subtext}" />
        </DataGrid.Columns>
      </DataGrid>
    </DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>
有了这个XAML设置,我只需使用tabcontrol.Items将Items添加到tabcontrol中。添加(新MyTabItem)。

然后我尝试了另一个XAML设置,我绑定了tabcontrol。Itemsource转换为代码隐藏中的ObservableCollection。同样,如果绑定属性更改,选项卡内容也不会更新:(

)

我还尝试在ViewModel中制作CurrentItem属性,并将其用作窗口。资源,然后将Tabcontrol内容绑定到

{Binding Source={StaticResource CurrentItem}, Path=Text}

每当我改变选项卡时,我都会更新视图模型中的CurrentItem,但它也没有更新更改。

I'm pretty out of ideas:

WPF TabControl Header和Content没有更新

您需要实现INotifyPropertyChanged

请记住,在。net 4.5中有一个新属性简化了这个任务,请看这里

下面是一个示例,将其应用到两个类中,列表将需要变成ObservableCollection:

private ObservableCollection<MyTabContent> _contents = new  ObservableCollection<MyTabContent>();
public ObservableCollection<MyTabContent> Contents { get { return _contents; } }

public class MyTabContent : INotifyPropertyChanged
{
    private int _id;
    int ID {
        get{ return _id; }
        set{ _id = value; OnPropertyChanged(); }
    }
    private string _subText;
    public string Subtext {
        get{ return _subText; }
        set{ _subText= value; OnPropertyChanged(); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    { 
        if (PropertyChanged!= null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}