2010-01-17 7 views
4

У меня проблемы с чем-то, что кажется, должно быть очень простым, но на самом деле оказалось довольно сложным.Настойчивость WPF UI в TabControl

Допустим, у вас есть элемент управления TabControl, связанный с источником объектов ViewModels и элементами, отображаемыми с помощью DataTemplate. Теперь скажем, что DataTemplate состоит из сетки с двумя столбцами и разделителя Grid для изменения размеров столбцов.

Проблема заключается в том, что при изменении размеров столбцов на одной вкладке и переключении на другую вкладку также изменяются размеры столбцов. Это связано с тем, что TabControl использует DataTemplate среди всех вкладок. Этот недостаток устойчивости к пользовательскому интерфейсу применяется ко всем элементам шаблона, которые могут привести к разочарованию при настройке различных компонентов пользовательского интерфейса. Другим примером является положение прокрутки в DataGrid (на вкладке). DataGrid с несколькими элементами будет прокручиваться вне поля зрения (только одна строка будет видна), если DataGrid с большим количеством строк прокручивается вниз на другой вкладке. Вдобавок к этому, если TabControl имеет различные элементы, определенные в нескольких DataTemplates, представление сбрасывается при переключении между элементами типов differenet. Я понимаю, что этот подход экономит ресурсы, но возникающая функциональность кажется довольно противоречивой ожидаемому поведению пользовательского интерфейса.

И поэтому мне интересно, есть ли решение/обходное решение для этого, поскольку я уверен, что это то, с чем раньше сталкивались другие. Я заметил несколько подобных вопросов на других форумах, но не было реального решения. Один об использовании AdornerDecorator, но, похоже, не работает при использовании с DataTemplate. Я не заинтересован в привязке всех свойств пользовательского интерфейса (например, ширины столбца, позиции прокрутки) к моим ViewModels, и на самом деле я попробовал его для простого примера GridSplitter, и мне не удалось заставить его работать. Ширина параметра ColumnDefinitions не обязательно зависит от разделителя сетки. Несмотря на это, было бы неплохо, если бы это было общее решение. Есть предположения?

Если я отключаю TabControl и использую ItemControl, я столкнусь с аналогичной проблемой? Можно ли изменить стиль TabControl, чтобы он не делил ContentPresenter между вкладками?

ответ

1

Я уже давно занимаюсь этим. Наконец, вместо того, чтобы пытаться исправить/изменить TabControl, я просто воссоздал его функциональность. Это действительно хорошо работает. Я сделал Tab'like'Control из Listbox (заголовки Tab) и ItemsControl. Главное было установить параметр ItemsPanelTemplate элемента ItemsControl в сетку. Немного стилизации и DataTrigger для управления видимостью предметов и вуаля. Он отлично работает, каждая «вкладка» является уникальным объектом и сохраняет все его пользовательские интерфейсы, такие как положение прокрутки, выбор, ширина столбцов и т. Д. Любые недостатки или проблемы, которые могут возникнуть с этим типом решения?

 <DockPanel> 
      <ListBox 
       DockPanel.Dock="Top" 
       ItemsSource="{Binding Tabs}" 
       SelectedItem="{Binding SelectedTab}" 
       ItemContainerStyle="{StaticResource ImitateTabControlStyle}"> 
       <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
         <StackPanel 
          Orientation="Horizontal"> 
         </StackPanel> 
        </ItemsPanelTemplate> 
       </ListBox.ItemsPanel> 

       <ListBox.ItemTemplate> 
        <DataTemplate>        
         <StackPanel 
          Margin="2,2,2,0" 
          Orientation="Horizontal" > 
          <TextBlock 
           Margin="4,0" FontWeight="Bold" 
           Padding="2" 
           VerticalAlignment="Center" HorizontalAlignment="Left" 
           Text="{Binding Name}" > 
          </TextBlock> 
          <Button 
           Margin="4,0" 
           Command="{Binding CloseCommand}"> 
           <Image Source="/TERM;component/Images/Symbol-Delete.png" MaxHeight="20"/> 
          </Button> 
         </StackPanel>        
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
      <ItemsControl  
       ItemsSource="{Binding Tabs}"> 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <Grid /> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <ContentControl         
          Content="{Binding}"> 
          <ContentControl.Style> 
           <Style> 
            <Style.Triggers> 
             <DataTrigger 
              Binding="{Binding IsSelected}" Value="False"> 
              <Setter Property="ContentControl.Visibility" Value="Hidden" />             
             </DataTrigger> 
            </Style.Triggers> 
           </Style> 
          </ContentControl.Style> 
         </ContentControl> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl>     
     </DockPanel> 
+0

Вы можете предоставить ресурс «ImitateTabControlStyle» для его проверки. Звучит неплохо –