2008-09-29 7 views
28

WPF के लिए ViewModel-ViewModel पैटर्न के तहत, मैं हाइट्स और ग्रिड नियंत्रण के लिए विभिन्न परिभाषाओं की चौड़ाई DataBind कोशिश कर रहा हूँ, इसलिए मैं एक GridSplitter उपयोग करने के बाद करने के लिए मूल्यों उपयोगकर्ता उन्हें सेट स्टोर कर सकते हैं। हालांकि, सामान्य पैटर्न इन विशेष गुणों के लिए काम नहीं कर रहा है।मैं कॉलमडिफिनिशन की चौड़ाई या पंक्ति परिभाषा की ऊंचाई कैसे डेटाबेस करूं?

नोट: मैं इसे एक संदर्भ प्रश्न के रूप में पोस्ट कर रहा हूं कि मैं पोस्ट कर रहा हूं क्योंकि Google मुझे विफल कर रहा है और मुझे इसे स्वयं से बाहर करना पड़ा। मेरा पालन करने का मेरा जवाब।

उत्तर

17

मुझे पता चला gotchas की एक संख्या इस प्रकार थे:

  1. हालांकि यह XAML में एक डबल की तरह दिखाई देते हैं, एक * परिभाषा के ऊंचाई या चौड़ाई के लिए वास्तविक मूल्य एक 'GridLength' struct है।
  2. सभी GridLength के गुणों केवल पढ़ने के लिए कर रहे हैं, तो आप एक नया एक हर बार जब आप इसे बदल बनाना होगा।
  3. WPF, चौड़ाई और ऊंचाई में हर दूसरे संपत्ति के विपरीत '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:

इसके अतिरिक्त, मैं निम्नलिखित कोड का इस्तेमाल किया

<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 ViewModel में" गलत है, के बाद से इस तरह के WPF बहुत databinding ही MVVM पैटर्न, के बारे में निर्माणों का एक बहुत है। आप कह सकते हैं "ग्रिड लम्बाई दृश्य के लिए विशिष्ट है", इसके बजाए (जब तक कि यह डोमेन समस्या का हिस्सा न हो, जैसे कि डेटा-विज़ुअलाइजेशन अनुप्रयोगों में, जिनका बहुत पर्स्यूज़ लेआउट और चीजों को प्रदर्शित करता है)। लेकिन यकीन है कि यह विवादास्पद है ... – heltonbiker

+0

@heltonbiker "ग्रिडलेथेंथ दृश्य के लिए विशिष्ट है" अधिक सटीक है। जब तक कि आपका व्यावसायिक तर्क पूरी तरह से या आंशिक रूप से UI लेआउट (डिज़ाइन) –

4

एक और संभावना है के बाद से आप की परवरिश GridLength और int के बीच परिवर्तित करने, एक 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 -फिंड-गोवरिंग-फ्रेमवर्कलेमेंट-फॉर-टार्गेट-एलिमेंट – dzendras

+0

डब्लूपीएफ में पहले से ही एक ग्रिड लम्बाई कनवर्टर क्लास है। क्या इसका उपयोग करना संभव होगा? – heltonbiker

+4

@heltonbiker दुर्भाग्य से, GridLengthConverter ITypeConverter बल्कि IValueConverter से लागू करता है, और इसलिए एक WPF बाइंडिंग रूपांतरण के रूप में इस्तेमाल नहीं किया जा सकता। –

2

सबसे आसान समाधान है बस इन गुणों के लिए स्ट्रिंग सेटिंग का उपयोग करने ताकि WPF होगा स्वचालित रूप से बिना किसी अतिरिक्त काम के GridLengthConverter का उपयोग करके उनका समर्थन करें।

संबंधित मुद्दे