2016-11-08 2 views
1

Поскольку мое приложение WPF несколько раз использует GridSplitter s, я хочу извлечь этот фрагмент XAML в отдельный UserControl.GridSplitter действует по-разному при перемещении на внешний ресурс (UserControl)

Конечно, использование ResourceDictionary будет приятнее. Но таким образом, я могу только определить ControlTemplate для содержимого сплиттера и использовать его в пределах Template-атрибута впоследствии - который удаляет возможность определять все эти атрибуты GridSplitter только один раз, а затем последовательно их использовать.

GridSplitterUserControl, GridSplitter.xaml:

<GridSplitter HorizontalAlignment="Stretch" Margin="3" ResizeBehavior="PreviousAndNext" 
       ResizeDirection="Columns" VerticalAlignment="Stretch"> 
    <GridSplitter.Template> 
    <ControlTemplate TargetType="{x:Type GridSplitter}"> 
     <Grid> 
     <Button Content="⁞" /> 
     <Rectangle Fill="#00FFFFFF" /> 
     </Grid> 
    </ControlTemplate> 
    </GridSplitter.Template> 
</GridSplitter> 

Использование в MainWindow.xaml:

<Window 
     (...) 
     xmlns:uc="clr-namespace:Yoda.Frontend.Resources" 
     (...)> 
    <Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition MinWidth="100" Width="200" /> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition MinWidth="400" Width="*" /> 
    </Grid.ColumnDefinitions> 
    <!-- (...) --> 
    <uc:GridSplitter Grid.Column="1" /> 
    <!-- (...) --> 
    </Grid> 
    <!-- (...) --> 
</Window> 

Результат использования приведенный выше код является сплиттер, который может Не двигайтесь в любом направлении.

Однако, используя упомянутый выше подход для словаря ResourceDictionary, я получаю подвижный GridSplitter.
Но, несмотря на то, что он отлично работает непосредственно в MainWindow.xaml, он только изменяет размеры третьей колонки сетки.

Уверенный, установка Width не рекомендуется при использовании GridSplitter. Но почему он работает всякий раз, когда разделитель определяется в главном окне и только не делает этого при использовании в качестве UserControl? И как исправить это в MVVM, без кода?

ответ

1

В случае, если вы только что иметь симпатичный сплиттер, вы можете использовать этот код:

<Grid.ColumnDefinitions> 
    <ColumnDefinition MinWidth="100" Width="Auto" /> 
    <ColumnDefinition MinWidth="20" Width="Auto" /> 
    <ColumnDefinition MinWidth="400" Width="Auto" /> 
</Grid.ColumnDefinitions> 
<!-- (...) --> 
<GridSplitter Grid.Column="1" Background="Gray" HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch" /> 
<TextBlock Text="⁞" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" 
      IsHitTestVisible="False" /> 
<!-- (...) --> 

Другим решением было бы определить ControlTemplate как ресурс, а затем использовать его для GridSplitter:

<Window.Resources> 
    <ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter"> 
     <Grid Background="Transparent"> 
      <Button Content="⁞" IsHitTestVisible="False" /> 
      <Rectangle Fill="#00FFFFFF" IsHitTestVisible="False" /> 
     </Grid> 
    </ControlTemplate> 
</Window.Resources> 
<Grid> 
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition MinWidth="100" Width="Auto" /> 
      <ColumnDefinition MinWidth="20" Width="Auto" /> 
      <ColumnDefinition MinWidth="400" Width="Auto" /> 
     </Grid.ColumnDefinitions> 
     <!-- (...) --> 
     <GridSplitter Grid.Column="1" Template="{StaticResource gridSplitter}" /> 
     <!-- (...) --> 
    </Grid> 
    <!-- (...) --> 
</Grid> 

Существует также решение, если вы действительно хотите использовать заданные свойства в шаблоне сплиттера: используйте стиль для их добавления. Это будет выглядеть следующим образом:

<Window.Resources> 
    <ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter"> 
     <Grid Background="Transparent"> 
      <Button Content="⁞" IsHitTestVisible="False"/> 
      <Rectangle Fill="#00FFFFFF" IsHitTestVisible="False"/> 
     </Grid> 
    </ControlTemplate> 
    <Style TargetType="{x:Type GridSplitter}" x:Key="styleGridSplitter"> 
     <Setter Property="Template" Value="{StaticResource gridSplitter}" /> 
     <Setter Property="ResizeBehavior" Value="PreviousAndNext" /> 
     <Setter Property="ResizeDirection" Value="Columns" /> 
     <Setter Property="VerticalAlignment" Value="Stretch" /> 
     <Setter Property="HorizontalAlignment" Value="Stretch" /> 
     <Setter Property="Margin" Value="3" /> 
    </Style> 
</Window.Resources> 
<Grid> 
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition MinWidth="100" Width="Auto" /> 
      <ColumnDefinition MinWidth="20" Width="Auto" /> 
      <ColumnDefinition MinWidth="400" Width="Auto" /> 
     </Grid.ColumnDefinitions> 
     <!-- (...) --> 
     <GridSplitter Grid.Column="1" Style="{StaticResource styleGridSplitter}"/> 
     <!-- (...) --> 
    </Grid> 
    <!-- (...) --> 
</Grid> 

+0

Прежде всего: благодаря _A lot_ этого _awesome_ и разнообразный ответ. Я перепутал, что 'ControlTemplate' нужно определять в стиле' Style', а не наоборот. Оттуда я даже смог улучшить ваш ответ. :) Итак, я с радостью принимаю ваш ответ, как только вы можете прояснить одну оставшуюся проблему: почему мне нужно переключиться с «StaticResource» на «DynamicResource», чтобы избежать исключений во время выполнения? ** Примечание: ** Я определил «GridSplitter» в отдельном файле XAML для включения в «ResourceDictionary.MergedDictionaries» App.xaml (рядом с одним для «ContextMenu», который не связан). – Yoda

+0

Решения, которые я предложил, не используют другой элемент управления, но по умолчанию тот, который присутствует в WPF. Ваше решение теперь использует контроль, сделанный вами? –

+0

Нет, я просто переключился на третье решение (с добавлением, которое я упомянул в своем первом комментарии к отдельному файлу и включая этот файл в «ResourceDictionary.MergedDictionaries» App.xaml). BTW: Спасибо, что намекнул мне на «IsHitTestVisible»!:) – Yoda

Смежные вопросы