2008-09-29 8 views
28

WPF 용 View-Model-ViewModel 패턴에서 GridSplitter를 사용한 후 사용자가 설정 한 값을 저장할 수 있도록 그리드 컨트롤에 대한 다양한 정의의 높이와 너비를 데이터 바인딩하려고합니다. 그러나 정상적인 패턴은 이러한 특정 속성에 대해 작동하지 않습니다.어떻게 ColumnDefinition의 너비 또는 RowDefinition의 높이를 데이터 바인딩합니까?

참고 : 저는 게시자가 Google에서 실패로 나와 게시하는 참조 질문으로 게시하고 있으며, 직접 해결해야했습니다. 따라야 할 내 대답.

답변

17

내가 발견 한 개는의 수 있었다 : 그것은 XAML에서 더블처럼 보이는 경우가 있지만

  1. 는 A * 정의의 높이 또는 폭의 실제 값이 'GridLength'구조체이다가.
  2. GridLength의 모든 속성은 읽기 전용이므로 변경할 때마다 새 속성을 만들어야합니다.
  3. WPF의 다른 모든 속성과 달리 Width 및 Height는 데이터 바인딩 모드를 'TwoWay'로 기본 설정하지 않으므로 수동으로 설정해야합니다.

    private GridLength myHorizontalInputRegionSize = new GridLength(0, GridUnitType.Auto) 
    public GridLength HorizontalInputRegionSize 
    { 
        get 
        { 
         // If not yet set, get the starting value from the DataModel 
         if (myHorizontalInputRegionSize.IsAuto) 
          myHorizontalInputRegionSize = new GridLength(ConnectionTabDefaultUIOptions.HorizontalInputRegionSize, GridUnitType.Pixel); 
         return myHorizontalInputRegionSize; 
        } 
        set 
        { 
         myHorizontalInputRegionSize = value; 
         if (ConnectionTabDefaultUIOptions.HorizontalInputRegionSize != myHorizontalInputRegionSize.Value) 
         { 
          // Set the value in the DataModel 
          ConnectionTabDefaultUIOptions.HorizontalInputRegionSize = value.Value; 
         } 
         OnPropertyChanged("HorizontalInputRegionSize"); 
        } 
    } 
    

    그리고 XAML :

thusly 히, 나는 다음과 같은 코드를 사용하면 GridLengthint 사이의 변환을 제기하기 때문에,

<Grid.RowDefinitions> 
    <RowDefinition Height="*" MinHeight="100" /> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" /> 
</Grid.RowDefinitions> 
+9

GridLength는 WPF에만 해당되므로 ViewModel 레이어에 속하지 않습니다. –

+2

저는 WPF가 MVML 패턴과 관련하여 매우 데이터 바인딩과 관련하여 많은 구조를 가지고 있기 때문에 "ViewModel의 WPF 없음"이라는 신념이 잘못되었다고 생각합니다. "GridLength는 VIEW에 한정됩니다"라고 말할 수 있습니다 (도메인 시각 문제의 일부인 경우가 아니라면, 데이터 시각화 응용 프로그램에서 레이아웃 및 표시 등을하는 것이 가장 이상적입니다). 하지만 확실한 논란의 여지가 있습니다. – heltonbiker

+0

@heltonbiker "GridLength는 VIEW에 고유합니다"가 더 정확합니다. 비즈니스 로직이 UI 레이아웃 (디자인) –

4

또 다른 가능성을 IValueConverter을 만드는 것입니다 Width에 바인드 할 때 사용하십시오. IValueConverter 또한 ConvertTo()ConvertBack() 메서드를 모두 가지고 있기 때문에 양방향 바인딩을 처리합니다.

public class GridLengthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     double val = (double)value; 
     GridLength gridLength = new GridLength(val); 

     return gridLength; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     GridLength val = (GridLength)value; 

     return val.Value; 
    } 
} 

당신은 다음 바인딩에 컨버터를 이용할 수있다 : 다음과 같이

34

IValueConverter 만들기

<UserControl.Resources> 
    <local:GridLengthConverter x:Key="gridLengthConverter" /> 
</UserControl.Resources> 
... 
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
            Mode=TwoWay, 
            Converter={StaticResource gridLengthConverter}}" /> 
+0

에만 국한되는 경우가 아니면 매우 유사한 문제에 대한 해결책을 찾으려면 http://stackoverflow.com/questions/7660967/wpf-error-cannot을 참조하십시오. -find-govering-frameworkelement-for-target-element – dzendras

+0

Wpf에는 이미 GridLengthConverter 클래스가 있습니다. 그대로 사용할 수 있습니까? – heltonbiker

+4

@heltonbiker 불행히도 GridLengthConverter는 IValueConverter가 아닌 ITypeConverter를 구현하므로 WPF 바인딩 변환으로 사용할 수 없습니다. –

2

가장 쉬운 솔루션은 단순히 이러한 속성에 대한 문자열 설정을 사용하는 WPF가 있도록 추가 작업없이 GridLengthConverter를 사용하여 자동으로 지원합니다.