ViewModel में एक बूल मान के लिए एक बटन की दृश्यता बांधना


122

मैं अपने ViewModel में बटन की दृश्यता को एक बूल मान से कैसे जोड़ सकता हूं?

<Button Height="50" Width="50" Style="{StaticResource MyButtonStyle}"
    Command="{Binding SmallDisp}" CommandParameter="{Binding}" Cursor="Hand"
    Visibility="{Binding Path=AdvancedFormat}" />

एक पर नजर डालें CalcBinding
VivekDev

जवाबों:


204

मान AdvancedFormatलेना एक है bool, आपको घोषणा करने और उपयोग करने की आवश्यकता है BooleanToVisibilityConverter:

<!-- In your resources section of the XAML -->
<BooleanToVisibilityConverter x:Key="BoolToVis" />

<!-- In your Button declaration -->
<Button
 Height="50" Width="50"
 Style="{StaticResource MyButtonStyle}"
 Command="{Binding SmallDisp}" CommandParameter="{Binding}" 
Cursor="Hand" Visibility="{Binding Path=AdvancedFormat, Converter={StaticResource BoolToVis}}"/>

नोट को जोड़ा Converter={StaticResource BoolToVis}

यह MVVM के साथ काम करते समय एक बहुत ही सामान्य पैटर्न है। सिद्धांत रूप में आप अपने आप को ViewModel संपत्ति पर रूपांतरण कर सकते हैं (यानी सिर्फ संपत्ति को स्वयं प्रकार बनाएं Visibility) हालांकि मैं ऐसा नहीं करना पसंद करूंगा, क्योंकि अब आप चिंताओं के पृथक्करण के साथ खिलवाड़ कर रहे हैं। किसी आइटम की दृश्यता वास्तव में दृश्य तक होनी चाहिए।


2
@ रेम्म ० एंड। ViewModel केवल एक बूलियन देता है, जो एक स्थिति का संकेत देता है। यदि आपका दृश्य उस बूलियन की व्याख्या करने के लिए होता है जैसे कि कुछ दिखाना है या नहीं, तो यह दृश्य पर निर्भर है। ध्यान दें कि एक अन्य दृश्य अभी भी इसकी अलग तरह से व्याख्या कर सकता है।
dlev

2
हां, क्योंकि यह सिर्फ एक सहायक वर्ग है जो एक मूल्य की मालिश करता है। दृश्यमॉडल अभी भी आपके मॉडल और आपके दृश्य के बीच में रहेगा।
कोडविअर

2
इसके अलावा, ध्यान रखें कि MVVM एक डिज़ाइन पैटर्न है, और इस प्रकार आपको इसके कार्यान्वयन के बारे में अपने स्वयं के नियमों को लागू करना होगा। इसके अतिरिक्त ऐसे समय भी होंगे जब किसी चीज को पूरा करने का एकमात्र तरीका मॉडल के बाहर, व्यूमॉडल या व्यू का एक्सएएमएल भाग होगा। संहिताबिंदु में कुछ डालना पाप नहीं है। यदि संभव हो तो ViewModel में डालने के लिए यह MVVM पैटर्न के अनुरूप है।
कोडवियार

3
व्यक्तिगत रूप से, मुझे अपने ViewModels में टाइप विजिबिलिटी की संपत्ति डालने में कोई आपत्ति नहीं है। मुझे पता है कि यह मेरे लिए विधर्मी है, लेकिन मेरे लिए, यह दृश्य को अधिक लचीलापन देता है, कम नहीं। यदि कोई दृश्य इसका उपयोग नहीं करना चाहता है, तो इसे नहीं करना है और यदि कोई करता है, तो यह कन्वर्टर्स या स्टाइल ट्रिगर्स के साथ खेलने के दर्द को काट देता है। हां, यह मेरा ViewModel एक प्रस्तुति प्रौद्योगिकी (WPF बनाम ASP.Net MVC, उदाहरण के लिए) को थोड़ा सा जोड़ता है, लेकिन मुझे शायद ही कभी उन तकनीकों और मिश्रण को मिलाए जाने की आवश्यकता है यदि मैं कभी भी मुझे डराता नहीं हूं, तो बहुत।
जैकब प्रोफिट

1
BooleanToVisibilityConverter वर्तमान में विंडोज फोन UI के लिए उपलब्ध नहीं है, हालांकि इस जवाब ने एक कार्यान्वयन stackoverflow.com/a/20344739/595473
CosworthTC

97

एक तीसरा तरीका है जिसमें एक कनवर्टर या आपके दृश्य मॉडल में बदलाव की आवश्यकता नहीं है: एक शैली का उपयोग करें:

<Style TargetType="Button">
   <Setter Property="Visibility" Value="Collapsed"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding IsVisible}" Value="True">
         <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

मैं इस तकनीक को पसंद करता हूं क्योंकि मैं इसका उपयोग बहुत सारे मामलों में करता हूं जहां मैं जो बंधन में हूं, वह बूलियन नहीं है - उदाहरण के लिए एक तत्व का प्रदर्शन केवल अगर DataContextयह शून्य नहीं है, या बहु-राज्य प्रदर्शनों को लागू करना जहां विभिन्न लेआउट के आधार पर दिखाई देते हैं। दृश्य मॉडल में एक एनम की स्थापना।


5
आम तौर पर, मुझे लगता है कि कन्वर्टर्स एक हैक हैं और मैं उन्हें पसंद नहीं करता। मुझे लगता है कि यह एक इंजीनियरिंग दृष्टिकोण से पेशेवरों और विपक्ष के एक शांत मूल्यांकन के बजाय मेरे कर्कश व्यक्तिगत स्वाद का मामला है, लेकिन उन्हें इससे बचें।
रॉबर्ट रॉसनी

1
मैं यह नहीं कह सकता कि मैं उनका उपयोग करता हूं जो अक्सर या तो होता है। वे थोड़े नखरे करते हैं (sic?)। आपकी पोस्ट के बाद, मुझे याद आया कि मैंने पिछली परियोजनाओं में काफी कुछ शैलियों / ट्रिगर्स का उपयोग किया था ...
CodeWarrior

मेरे पास एक था TextBlockजो TextWrapping="Wrap"दिया गया था। अब उस रैपिंग प्रॉपर्टी को इसमें सेट नहीं किया गया है।
अमित झा

10

बूलियन से दृश्यता में # ग में 2 तरह से रूपांतरण

using System;
using System.Windows;
using System.Windows.Data;

namespace FaceTheWall.converters
{
    class BooleanToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is Boolean && (bool)value)
            {
                return Visibility.Visible;
            }
            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is Visibility && (Visibility)value == Visibility.Visible)
            {
                return true;
            }
            return false;
        }
    }
}

7
जैसा कि पहले ही उल्लेख किया गया है, वहाँ पहले से ही WPF में बनाया गया है। आप अपना खुद का बनाने की जरूरत नहीं है।
जूता

4

आम तौर पर इसे करने के दो तरीके हैं, एक कनवर्टर वर्ग या व्यूमॉडल में एक संपत्ति जो अनिवार्य रूप से आपके लिए मूल्य को परिवर्तित करती है।

यदि यह एक बंद रूपांतरण है तो मैं संपत्ति दृष्टिकोण का उपयोग करता हूं। यदि आप इसे फिर से उपयोग करना चाहते हैं, तो कनवर्टर का उपयोग करें। नीचे, कनवर्टर का एक उदाहरण खोजें:

<ValueConversion(GetType(Boolean), GetType(Visibility))> _
Public Class BoolToVisibilityConverter
    Implements IValueConverter

    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert

        If value IsNot Nothing Then
            If value = True Then 
                Return Visibility.Visible
            Else
                Return Visibility.Collapsed
            End If
        Else
            Return Visibility.Collapsed
        End If
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Throw New NotImplementedException
    End Function
End Class

एक ViewModel संपत्ति विधि बस बूलियन संपत्ति मूल्य की जाँच करेगा, और उसी के आधार पर एक दृश्यता लौटाएगा। INotifyPropertyChanged को लागू करना सुनिश्चित करें और इसे बूलियन और दृश्यता दोनों गुणों पर ठीक से अपडेट करने के लिए कॉल करें।


12
WPF में पहले से ही एक BooleanToVisibilityConverter अंतर्निहित है।
CodeNaked

मुझे इसका एहसास नहीं था। यह वास्तव में कुछ और था जिसे मैंने इस परिदृश्य में फिट करने के लिए संपादित किया। इतना बेहतर है अगर वहाँ एक पूर्वनिर्मित है।
कोडवायर

3

इसे बहुत ही सरल तरीके से प्राप्त किया जा सकता है। 1. इसे दृश्य में लिखें।

<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="30">
<Button.Style>
        <Style TargetType="Button">
                <Setter Property="Visibility" Value="Collapsed"/>
                        <Style.Triggers>
                                <DataTrigger Binding="{Binding IsHide}" Value="True">
                                        <Setter Property="Visibility" Value="Visible"/>
                                    </DataTrigger>
                            </Style.Triggers>
            </Style>
    </Button.Style>

  1. निम्नलिखित बूलियन संपत्ति है जो सही / गलत मूल्य रखती है। निम्नलिखित कोड स्निपेट है। मेरे उदाहरण में यह संपत्ति UserNote वर्ग में है।

    public bool _isHide = false;
    
    public bool IsHide
    {
    
    get { return _isHide; }
    
    set
        {
            _isHide = value;
                OnPropertyChanged("IsHide");
        }
    } 
  2. यह वह तरीका है जिससे ईशाइड प्रॉपर्टी को वैल्यू मिलती है।

    userNote.IsHide = userNote.IsNoteDeleted;

2

दृश्य में:

<Button
 Height="50" Width="50"
 Style="{StaticResource MyButtonStyle}"
 Command="{Binding SmallDisp}" CommandParameter="{Binding}" 
Cursor="Hand" Visibility="{Binding Path=AdvancedFormat}"/>

दृश्य में मॉडल:

public _advancedFormat = Visibility.visible (whatever you start with)

public Visibility AdvancedFormat
{
 get{return _advancedFormat;}
 set{
   _advancedFormat = value;
   //raise property changed here
}

आपको प्रॉपर्टी चेंज किए गए इवेंट की आवश्यकता होगी

 protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
        PropertyChanged.Raise(this, e); 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
    } 

इस तरह वे मॉडल-व्यू-व्यूमॉडल का उपयोग करते हैं

लेकिन जब से आप चाहते हैं कि यह एक बूलियन से बंधा हो, तो आपको कुछ कनवर्टर की आवश्यकता होगी। दूसरा तरीका यह है कि एक बूलियन को बाहर सेट किया जाए और जब उस बटन पर क्लिक किया जाए, तो अपनी वांछित दृश्यता के लिए property_advancedFormat सेट करें।


private Visibility _advancedFormat = Visibility.visibleयह UWPधन्यवाद पर ठीक काम करता है ।
रुबस्टैकऑवरफ्लो

1

चूंकि विंडोज 10 15063 ऊपर की तरफ है

चूंकि विंडोज 10 का निर्माण 15063 है, इसलिए "इंप्लीसेंट विजिबिलिटी रूपांतरण" नामक एक नई सुविधा है जो मूल रूप से बूल मूल्य पर दृश्यता को बांधती है - एक कनवर्टर का उपयोग करने के लिए अब और कोई आवश्यकता नहीं है।

(देखें https://social.technet.microsoft.com/wiki/contents/articles/34846.uwp-compiled-binding-windows-10-anniversary-update.aspx#Implicit_Visibility_conversion )।

मेरा कोड (जो मानता है कि MVVM का उपयोग किया जाता है, और खाका 10 भी):

<!-- In XAML -->
<StackPanel x:Name="Msg_StackPanel" Visibility="{x:Bind ViewModel.ShowInlineHelp}" Orientation="Horizontal" Margin="0,24,0,0">
    <TextBlock Text="Frosty the snowman was a jolly happy soul" Margin="0,0,8,0"/>
    <SymbolIcon Symbol="OutlineStar "/>
    <TextBlock Text="With a corncob pipe and a button nose" Margin="8,0,0,0"/>
</StackPanel>

<!-- in companion View-Model -->
public bool ShowInlineHelp // using T10 SettingsService
{ 
    get { return (_settings.ShowInlineHelp); }
    set { _settings.ShowInlineHelp = !value; base.RaisePropertyChanged(); }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.