2014-06-12 1 views
3

템플릿 항목을 격자에 정렬하는 UserControl이 있습니다 (this 질문의 대답을 기반으로 함). 이제 그 격자의 열/행을 크기를 조정할 수있게 만들고 싶습니다.WPF UserControl은 사용자가 만든 DataTemplate에 GridSplitter를 첨부합니다.

지금 당장 마우스 이벤트를 감지하고 사용자가 국경 근처를 클릭하는지 계산할 수있는 약간의 해킹이 있습니다. 그렇다면 적절한 열을 조정합니다. 이 방법은 대부분 효과적이지만 MouseMove 이벤트가 비교적 느리게 실행되면서 문제가 발생하여 사용자가 올바른 위치를 클릭하기 어렵습니다. 또한 마우스를 이제는 추적 할 수없는 제어 영역 외부로 이동 했으므로 마지막 행/열의 크기를 확장 할 수 없습니다 (그러나 더 많은 작업으로이 문제를 해결할 수도 있음).

더 나은 해결책은 GridSplitters를 각 열/행에 추가하는 것입니다. 문제는, 내 UserControl ItemsControl 및 DataTemplate 항목을 만드는 데 사용하므로 스플리터를 추가하는 방법을 알아내는 데 문제가 있습니다. 사용자 정의 템플릿을 수정할 수 있습니까? 스플리터를 추가 할 다른 방법이 있습니까?

* EDIT *

여기에 내가 (격자 세포가 수동으로 정의 된 경우 대신 ItemsControl을 통해) 할 싶은 것이 예입니다. 이 예제는 여전히 마지막 행 크기 조정 문제를 해결하지 못한다는 점에 유의하십시오.

<Grid 
    Grid.Row="2" Grid.Column="1" 
    > 
    <Grid.RowDefinitions> 
     <RowDefinition Height="30"/> 
     <RowDefinition Height="30"/> 
     <RowDefinition Height="30"/> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 

    <TextBox Text="Row 0" Grid.Row="0"/> 
    <GridSplitter 
     Grid.Row="0" 
     Height="5" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Bottom" 
     Background="Transparent"/> 
    <TextBox Text="Row 1" Grid.Row="1"/> 
    <GridSplitter 
     Grid.Row="1" 
     Height="5" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Bottom" 
     Background="Transparent"/> 
    <TextBox Text="Row 2" Grid.Row="2"/> 
    <GridSplitter 
     Grid.Row="2" 
     Height="5" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Bottom" 
     Background="Transparent"/> 
</Grid> 
+0

동일한 XAML을 게시 할 수 있습니까? 샘플 이미지도 있으면 감사하겠습니다. – pushpraj

+0

찾고있는 XAML을 정확히 이해하고 있는지 확실하지 않습니다. 나는 그것을 추가했다 ... 그것을 커버합니까? – ryan0270

+0

사용자 정의 컨트롤에 격자가 정의되어 있습니까? 눈금을 정의하는 컨트롤의 XAML을 게시 할 수 있습니까? –

답변

0

열은보기 모델의 속성에 열의 너비를 바인딩하여 수행 할 수 있습니다. 이렇게하면 GridSplitter가 움직이면서 속성을 업데이트하고 다른 항목을 업데이트합니다.

행의 경우 DataTemplate의 아래쪽에 GridSplitter를 추가하면 필요한 것을 제공해야합니다.

나는 설명하기 위해 약간의 해키 샘플 응용 프로그램을 만들어 :

내 창 : XAML에서

public partial class MainWindow 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = new Context(); 

     ItemsControl.ItemsSource = new ObservableCollection<Foo> 
      { 
       new Foo("Hello", "World1"), 
       new Foo("Hello1", "World2"), 
       new Foo("Hello2", "World3") 
      }; 
    } 
} 

:

다음 데이터 컨텍스트 및 항목을 사용

<ItemsControl Name="ItemsControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type utility:Foo}"> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="{Binding Path=DataContext.Width, RelativeSource={RelativeSource FindAncestor, AncestorType=utility:MainWindow}, Mode=TwoWay}" /> 
        <ColumnDefinition Width="5" /> 
        <ColumnDefinition Width="*" /> 
       </Grid.ColumnDefinitions> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="5" /> 
       </Grid.RowDefinitions> 
       <TextBlock Text="{Binding Path=Name}" Grid.Column="0" Grid.Row="0" Margin="5"/> 
       <GridSplitter Grid.Column="1" Grid.Row="0" Width="5" Height="Auto" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" ResizeDirection="Columns" /> 
       <TextBlock Text="{Binding Path=Title}" Grid.Column="2" Grid.Row="0" Margin="5"/> 
       <GridSplitter Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Height="5" Width="Auto" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndCurrent" ResizeDirection="Rows" /> 
      </Grid> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

public class Foo 
{ 
    public Foo(string name, string title) 
    { 
     Name = name; 
     Title = title; 
    } 

    public string Name { get; set; } 
    public string Title { get; set; } 
} 

public class Context : INotifyPropertyChanged 
{ 
    private GridLength _width = new GridLength(60); 

    public GridLength Width 
    { 
     get { return _width; } 
     set 
     { 
      if (_width == value) return; 
      _width = value; 
      RaisePropertyChanged(); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

주목해야 할 중요한 점 중 하나는 내 viewmodel의 Width 속성을 GridLength.Auto로 초기화 할 수 없다는 것입니다. 그렇지 않으면 모든 열이 정렬되지 않습니다.

+0

고마워,하지만 이건 나를 위해 작동하지 않습니다. 첫째, 데이터 템플릿을 명시 적으로 정의했지만 사용중인 데이터 템플릿이 다른 곳에 정의 된 일반 컨트롤을 만들고 있습니다. 둘째, Width 속성을 가진 ItemsSource와 그 너비 속성이 열 너비를 의미하므로이 컨트롤은 일반 컨트롤이기 때문에 신뢰할 수 없습니다. 또한 일렬로 정렬되는 각 항목에 대해 완전히 별도의 격자를 작성합니다. 앞에서 언급했듯이 너비가 자동으로 설정된 경우에는 더 이상 줄이 정렬되지 않으므로 이것은 약합니다. – ryan0270

+0

@ JimBobBennet 최종 메모 정보 : 동일한 [SharedSizeGroup] (http://msdn.microsoft. – Eirik

+0

@Eirik 아니요, 스플리터가 움직일 때 다른 열의 크기를 조정하지 않습니다. com/ko-kr/library/system.windows.controls.definitionbase.sharedsizegroup.aspx 나는 첫 번째 해결책으로 시도했지만 효과가 없었습니다. – JimBobBennett

관련 문제