DataTrigger जहां मूल्य शून्य नहीं है?


162

मुझे पता है कि मैं एक सेटर बना सकता हूं जो यह देखने के लिए जांचता है कि क्या मान NULL है और कुछ करें। उदाहरण:

<TextBlock>
  <TextBlock.Style>
    <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding SomeField}" Value="{x:Null}">
          <Setter Property="TextBlock.Text" Value="It's NULL Baby!" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>
</TextBlock>

लेकिन मैं "नहीं" मान के लिए कैसे जांच कर सकता हूं ... जैसा कि "नॉट नेल" में, या "नहीं = 3" में? क्या यह XAML में संभव है?

परिणाम: आपके उत्तर के लिए धन्यवाद ... मुझे पता था कि मैं एक वैल्यू कन्वर्टर कर सकता हूं (जिसका मतलब है कि मुझे कोड में जाना होगा, और जैसा कि मैंने सोचा था कि यह शुद्ध एक्सएएमएल नहीं होगा)। हालांकि, इस सवाल का जवाब है कि प्रभावी रूप से "नहीं" आप इसे शुद्ध एक्सएएमएल में नहीं कर सकते। हालाँकि, चयनित उत्तर, संभवतः उस तरह की कार्यक्षमता बनाने का सबसे अच्छा तरीका दिखाता है। अच्छा मिल गया।

जवाबों:


42

मैं DataTriggers के साथ एक समान सीमा में भाग गया, और ऐसा लगता है कि आप केवल समानता के लिए जांच कर सकते हैं। निकटतम चीज जो मैंने देखी है कि आप समानता के अलावा अन्य प्रकार की तुलना करने के लिए एक तकनीक हो सकती है।

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

DataTrigger की इस सीमा के आसपास कुछ हद तक एक कनवर्टर का उपयोग करके डेटा को एक विशेष मूल्य में मालिश करने के लिए उपयोग किया जा सकता है, जिसके बाद आप तुलना कर सकते हैं, जैसा कि रॉबर्ट मैनी के जवाब में बताया गया है।


10
दिलचस्प है कि पर्याप्त रूप से DataTrigger में वास्तव में एक आंतरिक क्षेत्र है जो यह नियंत्रित करता है कि यह समानता के लिए परीक्षण करता है या नहीं। दुर्भाग्य से आपको आवश्यक क्षेत्र में पहुंचने के लिए उचित मात्रा में प्रतिबिंबन करना होगा। समस्या यह है कि यह .net के अगले संस्करण में टूट सकता है।
कालेब वीयर

154

आप इसके लिए एक IValueConverter का उपयोग कर सकते हैं:

<TextBlock>
    <TextBlock.Resources>
        <conv:IsNullConverter x:Key="isNullConverter"/>
    </TextBlock.Resources>
    <TextBlock.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeField, Converter={StaticResource isNullConverter}}" Value="False">
                    <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

जहाँ IsNullConverter को कहीं और परिभाषित किया गया है (और इसके नाम स्थान को संदर्भित करने के लिए दृढ़ है):

public class IsNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value == null);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new InvalidOperationException("IsNullConverter can only be used OneWay.");
    }
}

एक अधिक सामान्य समाधान एक IValueConverter को लागू करना होगा जो कि कनवर्टरपैरमीटर के साथ समानता की जांच करता है, इसलिए आप किसी भी चीज़ के खिलाफ जांच कर सकते हैं, और न कि केवल अशक्त।


6
मुझे लगता है कि आप कनवर्टर को थोड़ा अधिक सामान्य बना सकते हैं और खिलाफ की तुलना करने के लिए एक मूल्य में पास करने के लिए कनवर्टरपैरमीटर का उपयोग कर सकते हैं (नॉट नॉट और नॉट 3 की तुलना करने के लिए दोनों का समर्थन करने के लिए 3.
J c

इसने मेरे लिए एक इलाज का काम किया - एक मल्टीपल ट्रिगर का उपयोग करके, यह इसे अच्छा और शक्तिशाली बनाता है।
बर्टी

149

यह एक धोखा है, लेकिन मैं सिर्फ एक डिफ़ॉल्ट शैली सेट करता हूं और फिर एक डेटाटाइगर का उपयोग करके इसे ओवररोड करता हूं यदि मूल्य शून्य है ...

  <Style> 
      <!-- Highlight for Reviewed (Default) -->
      <Setter Property="Control.Background" Value="PaleGreen" /> 
      <Style.Triggers>
        <!-- Highlight for Not Reviewed -->
        <DataTrigger Binding="{Binding Path=REVIEWEDBY}" Value="{x:Null}">
          <Setter Property="Control.Background" Value="LightIndianRed" />
        </DataTrigger>
      </Style.Triggers>
  </Style>

1
यह मेरे परिदृश्य के लिए सबसे अच्छा समाधान था! यह उत्तर प्रदान करने के लिए धन्यवाद!
स्कॉट

14
मुझे नहीं लगता कि यह एक हैक है, आपको इसे बहुत समय करने की आवश्यकता है; और यह ऐसा करने का सबसे साफ तरीका है।
अकोझी

3
डिफॉल्ट सेटर का इस्तेमाल बिना स्टाइल के किया जा सकता है। टाइप्टर टैग।
नेसर असदी

1
बस टिकट! मैं डिफ़ॉल्ट को उस नियंत्रण में रखता हूं जो स्टाइल का मालिक है, और यह पता नहीं लगा सका कि यह मेरी शैलियों को ओवरराइड क्यों करता रहा है :) धन्यवाद!
रिगार्ड्ट स्टेन

2
रास्ता बेहतर जवाब तो एक कनवर्टर का उपयोग कर ... सरल और साफ।
दासदास

27

अशक्त के साथ तुलना करें (जैसा कि माइकल नूनन ने कहा):

<Style>
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
     </Style.Triggers>
</Style>

अशक्त (एक कनवर्टर के बिना) के साथ तुलना करें:

<Style>
    <Setter Property="Visibility" Value="Collapsed" />
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
     </Style.Triggers>
</Style>

4
यह अब तक का सबसे सीधा जवाब है। मुझें यह पसंद है!
तीमुथियुस

15

मैं इसका उपयोग केवल एक बटन को सक्षम करने के लिए कर रहा हूं यदि एक सूची आइटम चुना गया है (अर्थात शून्य नहीं):

<Style TargetType="{x:Type Button}">
    <Setter Property="IsEnabled" Value="True"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding ElementName=lvMyList, Path=SelectedItem}" Value="{x:Null}">
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

4
कभी-कभी सबसे सरल समाधान स्पष्ट दृश्य में छिपा होता है। मेरा मानना ​​है, XAML कोड की व्याख्या ऊपर से नीचे तक की जाती है। इस तरह, बटन को पहले सक्षम किया जाएगा और फिर अक्षम किया जाएगा यदि सूची में कोई तत्व नहीं चुना गया है। लेकिन कृपया मुझे बताएं, क्या आइटम को एक बार सूची में चुने जाने के बाद अपडेट किया गया है?
फ्रेशचली

सूची आइटम चयनित होने पर बटन सक्षम किया जाता है, हाँ।
स्टीवकेव

14

आप Microsoft.Expression.Interactions.dllDataTrigger में क्लास का उपयोग कर सकते हैं जो एक्सप्रेशन ब्लेंड के साथ आते हैं ।

कोड नमूना:

<i:Interaction.Triggers>
    <i:DataTrigger Binding="{Binding YourProperty}" Value="{x:Null}" Comparison="NotEqual">
       <ie:ChangePropertyAction PropertyName="YourTargetPropertyName" Value="{Binding YourValue}"/>
    </i:DataTrigger
</i:Interaction.Triggers>

इस पद्धति का उपयोग करके आप के खिलाफ GreaterThanऔर LessThanभी ट्रिगर कर सकते हैं। इस कोड का उपयोग करने के लिए आपको दो dll का संदर्भ देना चाहिए:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll


6
<StackPanel.Style>
  <Style>
    <Setter Property="StackPanel.Visibility" Value="Visible"></Setter>
    <Style.Triggers>
      <DataTrigger  Binding="{Binding ElementName=ProfileSelectorComboBox, Path=SelectedItem.Tag}" Value="{x:Null}">
          <Setter Property="StackPanel.Visibility" Value="Collapsed"></Setter>
      </DataTrigger>
    </Style.Triggers>
  </Style>
</StackPanel.Style>

मैंने यहाँ उलटा तर्क का इस्तेमाल किया है ... जब मेरी कॉम्बोइट पॉपुलेटेड नहीं है तो अपने स्टैम्पपेल को अदृश्य करने के लिए सेट करना, यह बहुत अच्छा काम करता है!


6

रुकें! कोई कन्वर्टर नहीं! मैं इस आदमी की लाइब्रेरी को "बेचना" नहीं चाहता, लेकिन मुझे कन्वर्टर करने के तथ्य से नफरत थी जो मैं XAML में सामान की तुलना करना चाहता था।

तो इस लाइब्रेरी के साथ: https://github.com/Alex141/CalcBinding

आप ऐसा कर सकते हैं [और भी बहुत कुछ]:

सबसे पहले, विंडोज़ / userControl की घोषणा में:

<Windows....
     xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding"
>

फिर, टेक्स्टब्लॉक में

<TextBlock>
      <TextBlock.Style>
          <Style.Triggers>
          <DataTrigger Binding="{conv:Binding 'MyValue==null'}" Value="false">
             <Setter Property="Background" Value="#FF80C983"></Setter>
          </DataTrigger>
        </Style.Triggers>
      </TextBlock.Style>
    </TextBlock>

मैजिक पार्ट का कायल है: बाइंडिंग 'MYValue == null' । वास्तव में, आप अपनी इच्छा के अनुसार कोई भी शर्त निर्धारित कर सकते हैं [डॉक्टर को देखें]।

ध्यान दें कि मैं तीसरे पक्ष का प्रशंसक नहीं हूं। लेकिन यह पुस्तकालय नि: शुल्क है, और थोड़ा प्रभाव (परियोजना में केवल 2 .dll जोड़ें)।


5

मेरा समाधान DataContext उदाहरण (या MVVM का उपयोग करते हुए ViewModel) में है। मैं एक ऐसी संपत्ति जोड़ता हूं जो अगर मैं चाहता हूं तो नॉट नाल की शर्त पूरी होती है।

    Public ReadOnly Property IsSomeFieldNull() As Boolean
        Get
            Return If(SomeField is Null, True, False)
        End Get
    End Property

और उपरोक्त संपत्ति के लिए DataTrigger बाँध। नोट: VB.NET में ऑपरेटर का उपयोग करना सुनिश्चित करें I और IIF फ़ंक्शन नहीं, जो नल ऑब्जेक्ट्स के साथ काम नहीं करता है। फिर XAML है:

    <DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
      <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
    </DataTrigger>

3

यदि आप एक ऐसे समाधान की तलाश कर रहे हैं जिसमें IValueConverter का उपयोग नहीं होता है, तो आप हमेशा नीचे तंत्र के साथ जा सकते हैं

       <StackPanel>
            <TextBlock Text="Border = Red when null value" />
            <Border x:Name="border_objectForNullValueTrigger" HorizontalAlignment="Stretch" Height="20"> 
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Background" Value="Black" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ObjectForNullValueTrigger}" Value="{x:Null}">
                                <Setter Property="Background" Value="Red" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
            <TextBlock Text="Border = Green when not null value" />
            <Border HorizontalAlignment="Stretch" Height="20">
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Background" Value="Green" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Background, ElementName=border_objectForNullValueTrigger}" Value="Red">
                                <Setter Property="Background" Value="Black" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
            <Button Content="Invert Object state" Click="Button_Click_1"/>
        </StackPanel>

2

कनवर्टर:

public class NullableToVisibilityConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Collapsed : Visibility.Visible;
    }
}

बाइंडिंग:

Visibility="{Binding PropertyToBind, Converter={StaticResource nullableToVisibilityConverter}}"

2

आप किसी कन्वर्टर का उपयोग कर सकते हैं या अपने ViewModel में नई प्रॉपर्टी बना सकते हैं:

public bool CanDoIt
{
    get
    {
        return !string.IsNullOrEmpty(SomeField);
    }
}

और इसका उपयोग करें:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.