【问题标题】:WPF TabControl and DataGrid Combobox Columns return to initial position after Tab ChangedWPF TabControl 和 DataGrid Combobox 列在 Tab 更改后返回到初始位置
【发布时间】:2017-03-01 19:27:55
【问题描述】:

我有一个奇怪的问题,希望有人能帮助我解决我的问题。 这是问题所在。 我有一个应用程序需要在一个主要的TabControl 中动态创建TabItem。 主窗口在StackPanel 中有两个按钮,一个TabControl (将承载不同的TabItem 实例:

<DockPanel>
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
        <Button Content="Tab1" Command="{Binding AddTab}" CommandParameter="Tab1"/>
        <Button Content="Tab2" Command="{Binding AddTab}" CommandParameter="Tab2"/>
    </StackPanel>
    <TabControl DockPanel.Dock="Bottom" 
                ItemsSource="{Binding TabItems}" 
                SelectedItem="{Binding CurrentTabItem}"
                ItemTemplate="{StaticResource TabItemItemTemplate}"/>
</DockPanel>

在主窗口的 CodeBehind 中,将 DataContext 设置为一个新类,该类具有所有打开的 TabItem 实例的公共属性,用于选定的选项卡,以及用于添加新选项卡的命令:

    public ICommand AddTab { get; set; }

    public ObservableCollection<TabItem> TabItems { get; set; }
    private TabItem _currentTabItem;
    public TabItem CurrentTabItem 
               {
                 get {return _currentTabItem;} 
                 set
                     {
                       if(_currentTabItem == value) return;
                        _currentTabItem = value;
                        OnPropertyChanged(nameOf(CurrentTabItem);
                      }
               }

还有一个处理添加新标签的函数:

private void OnAddTabExecute(object obj)
    {
        var type = obj as string;
        if (type != null)
        {
            TabItem ti;
            if (type == "Tab1")
            {
                ti = new Tab1ViewModel();

            }
            else
            {
                ti = new Tab2ViewModel();
            }
            TabItems.Add(ti);
            CurrentTabItem = ti;
        }

在主窗口中,我声明了两个 DataTemplate,它们负责将选定的“Tab1ViewModel”或“Tab2ViewModel”“连接”到相应的视图:

    <DataTemplate DataType="{x:Type local:Tab1ViewModel}">
        <local:Tab1View/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Tab2ViewModel}">
        <local:Tab2View/>
    </DataTemplate>

到目前为止一切都很好!一切都很完美!!!然后在local:Tab1View.xaml 中添加另一个带有手动添加的 TabItems 的 TabControl:

<TabControl SelectedIndex="{Binding SelectedIndex}">
        <TabItem Header="New Tab">
            <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ThisThings}" CanUserAddRows="False">
                <DataGrid.Columns>
                    <DataGridTemplateColumn Header="Country">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding DataContext.Countries, 
                                    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                          DisplayMemberPath="Description"
                                          SelectedValuePath="ID"
                                          SelectedValue="{Binding CountryID}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem>
        <TabItem Header="Newer Tab">
            <TextBlock Text="This is test tab"/>
        </TabItem>
    </TabControl>

呈现的属性在 ViewModel 中,一切都按我的意愿加载,但问题出在:

  1. 我按下 Tab2 按钮,Tab2 出现(没问题) 2.我按下 Tab1 按钮,Tab1 加载,所有选定的数据都在组合框中:

注意所选国家:“保加利亚”(第 1 行)、“英国”(第 2 行)、“俄罗斯”(第 3 行)。 3. 将第 2 行的“UK”选项更改为“Germany”。

  1. 从内部 TabControl 中选择“Newer Tab”,然后返回“New Tab”。第 2 行的选择仍然是“德国”

5.从外部TabControl中选择“Tab 2”选项卡,然后返回“Tab 1”,选择从“德国”回到“英国”,就像在加载选项卡时一样。

我在某处红色,当您选择当前选项卡时,未选择的选项卡将从可视树中取出。但是为什么当我更改内部 TabControl 的选项卡时它没有发生呢?这个驱动器让我疯了。

我有这个项目的解决方案,如果有人需要,我可以提出。这是link 我希望它有效! (当您启动项目时,屏幕截图中的窗口会显示,通过单击“显示”按钮)

我会提出任何想法,这有什么问题,以及如何解决它


于 2017 年 1 月 3 日编辑 我正在提供Tab1ViewModel 的代码:

public class Tab1ViewModel : TabItem
{
    public ObservableCollection<Country> Countries { get; set; }
    public ObservableCollection<Thing> ThisThings { get; set; }

    public Thing ThisThing { get; set; }

    //public NewerTabViewModel NewerTabViewModel { get; set; }
    //public NewTabViewModel NewTabViewModel { get; set; }

    public int SelectedIndex { get; set; }

    public override string Header
    {
        get
        {
            return "Tab 1";
        }
    }

    public Tab1ViewModel()
    {

        ThisThings = new ObservableCollection<Thing>();
        ThisThings.Add(new Thing() { CountryID = 1, Name = "Greg" });
        ThisThings.Add(new Thing() { CountryID = 2, Name = "John" });
        ThisThings.Add(new Thing() { CountryID = 4, Name = "Sam" });

        ThisThing = new Thing()
        {
            CountryID = 3,
            Name = "Thingy",
            //HisThings = ThisThings
        };

        //NewTabViewModel = new NewTabViewModel(ThisThing);
        //NewerTabViewModel = new NewerTabViewModel(ThisThing);

        Countries = new ObservableCollection<Country>();
        Countries.Add(new Country() { ID = 1, Description = "Bulgaria" });
        Countries.Add(new Country() { ID = 2, Description = "UK" });
        Countries.Add(new Country() { ID = 3, Description = "USA" });
        Countries.Add(new Country() { ID = 4, Description = "Russia" });
        Countries.Add(new Country() { ID = 5, Description = "Germany" });
    }
}

【问题讨论】:

  • ThisThings 是一个集合吗?能否提供相关来源?我怀疑您的 SelectedValue="{Binding CountryID}" 绑定不起作用。
  • 嗨@DerrickMoeller,我刚刚使用初始化ThisThings 集合、ThisThing 对象和国家集合的方式编辑了原始帖子

标签: c# wpf xaml mvvm


【解决方案1】:

这是您的问题:每次选择标签时都会创建一个新的 TabItem:

这个:

private TabItem _currentTabItem;
public TabItem CurrentTabItem {get;set;}

应该是:

private TabItem _currentTabItem;
public TabItem CurrentTabItem 
                 {
                     get {return _currentTabItem;} 
                     set
                         {
                           if(_currentTabItem == value) return;
                            _currentTabItem = value;
                            OnPropertyChanged(nameOf(CurrentTabItem);
                          }
                   }

【讨论】:

  • 嗨@Nawed Nabi Zada,不,这不是解决方案。我已经尝试过了,它不会影响奇怪的行为。我将从原始帖子中编辑代码,以免混淆其他人。谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 2012-01-21
相关资源
最近更新 更多