WPF TabControl标题和内容没有更新?

时间:2013-03-27 17:48:02

标签: c# wpf data-binding user-interface tabcontrol

设置:我有一个带有0 ... n标签的tabcontrol,每个标签都绑定到一个类:

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

每个tabitem类都有许多tabcontent类。 (整个过程都是通过NHibernate获取的。)

我已经尝试了很多东西将MyTabItem的内容绑定到每个tabcontrol项的标题,并将MyTabContent的内容绑定到每个tabcontrol项的内容中的datagrid。

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

我真的不明白为什么我更改绑定类中的属性时我的tabcontrol内容不会更新。我尝试了两种不同的绑定策略,既可以显示内容,也可以在内容更改时进行更新。

我的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.Add(new MyTabItem)将项目添加到tabcontrol。

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

我还尝试在ViewModel中创建一个CurrentItem属性,并将其用作Window.Resource,然后将Tabcontrol内容绑定到

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

每当我更改标签时,我都会更新viewmodel中的CurrentItem,但是它也没有更新更改。

我几乎没有想法:(

1 个答案:

答案 0 :(得分:4)

您需要实施INotifyPropertyChanged

请记住,.NET 4.5中有一个新属性可以简化任务,看看here

以下是一个示例,将其应用于您的两个类,该列表需要成为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));
    }
}