4

设置:我有一个带有 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;}
}

每个 tabitem 类在它的集合中有许多 tabcontent 类。(整个事情都是通过 NHibernate 获取的)。

我尝试了很多方法来将 MyTabItem 的内容绑定到每个 tabcontrol 项的标题,并将 MyTabContent 的内容绑定到每个 tabcontrol 项的内容中的数据网格。

我可以在选项卡中显示所有内容,但是每当我更改绑定类中的属性时,UI 都不会更新。我尝试调用 InvalidateVisual,尝试调度 Render 事件,尝试在绑定上更新目标和更新源(最后两个抛出异常)。我已经在我的视图模型中实现了 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.Add(new MyTabItem) 将项目添加到 tabcontrol。

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

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

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

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

我几乎没有想法:(

4

1 回答 1

5

您需要实现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));
    }
}
于 2013-03-27T18:21:09.510 回答