Bagaimana saya bisa menyediakan beberapa kondisi untuk pemicu data di WPF?

173

Bagaimana saya bisa menyediakan beberapa kondisi untuk pemicu data di WPF?

Sumeru Suresh
sumber

Jawaban:

280

Gunakan tipe MultiDataTrigger

<Style TargetType="ListBoxItem">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Path=State}" Value="WA">
        <Setter Property="Foreground" Value="Red" />
      </DataTrigger>    
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding Path=Name}" Value="Portland" />
          <Condition Binding="{Binding Path=State}" Value="OR" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Background" Value="Cyan" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>
Gishu
sumber
28
Apakah ada cara untuk melakukan pernyataan "ATAU" di multiTrigger. misalnya nama = "portland" ATAU negara = "ATAU"
jasonk
12
@jasonk - Tidak yakin apakah Anda bisa melakukannya dengan MultiTrigger. Anda dapat menentukan dua pemicu untuk itu ..
Gishu
2
Jika ini adalah pernyataan kondisi ATAU sederhana, Anda dapat membalik logika sehingga berubah menjadi DAN. | kondisi1 | kondisi2 | hasil | | benar | benar | benar | | benar | salah | benar | | false | true | benar | | false | false | false | alih-alih memeriksa salah satu / ATAU benar, periksa apakah keduanya / DAN salah, dan tetapkan default ke true.
WeSam Abdallah
3
@WeSamAbdallah Anda tidak dapat memeriksa apakah kondisinya salah.
Jim Balter
4
Anda dapat memeriksa kondisi yang salah dengan konverter sederhana.
Paul
50

@jasonk - jika Anda ingin memiliki "atau" maka abaikan semua kondisi sejak (A dan B) <=> ~ (~ A atau ~ B)

tetapi jika Anda memiliki nilai selain boolean coba gunakan jenis konverter:

<MultiDataTrigger.Conditions>
    <Condition Value="True">
        <Condition.Binding>
            <MultiBinding Converter="{StaticResource conditionConverter}">
                <Binding Path="Name" />
                <Binding Path="State" />
            </MultiBinding>
        </Condition.Binding>
        <Setter Property="Background" Value="Cyan" />
    </Condition>
</MultiDataTrigger.Conditions>

Anda dapat menggunakan nilai-nilai dalam metode Konversi dengan cara apa pun yang Anda suka untuk menghasilkan kondisi yang cocok untuk Anda.

serin
sumber
3
Ah, langkah cerdas untuk meniadakan semuanya dan membalikkannya ke kondisi ATAU :)
myermian
8
Bisakah Anda sedikit memperluas jawaban ini? Saya tidak yakin bagaimana menggunakannya. Apa yang conditionConverterdilakukan? Bagaimana kita menetapkan "Portland" dan "OR" sebagai dua oropsi kita dalam contoh ini?
DLeh
4
@ cod3monk3y, tautan Anda rusak.
Spidermain50
22

Untuk menguraikan jawaban @ serine dan mengilustrasikan bekerja dengan kondisi multi-nilai non-sepele: Saya harus menunjukkan overlay "redup" pada item untuk kondisi boolean NOT a AND (b OR NOT c).

Untuk latar belakang, ini adalah pertanyaan "Pilihan Ganda". Jika pengguna memilih jawaban yang salah itu menjadi dinonaktifkan (redup dan tidak dapat dipilih lagi). Agen otomatis memiliki kemampuan untuk fokus pada pilihan tertentu untuk memberikan penjelasan (batas disorot). Ketika agen berfokus pada suatu item, itu tidak boleh meredup bahkan jika itu dinonaktifkan . Semua item yang tidak fokus ditandai tidak fokus , dan harus redup.

Logika untuk peredupan adalah sebagai berikut:

NOT IsFocused AND (IsDefocused OR NOT Enabled)

Untuk mengimplementasikan logika ini, saya membuat IMultiValueConverternama generik (canggung) untuk mencocokkan logika saya

// 'P' represents a parenthesis
//     !  a &&  ( b ||  !  c )
class NOT_a_AND_P_b_OR_NOT_c_P : IMultiValueConverter
{
    // redacted [...] for brevity
    public object Convert(object[] values, ...)
    {
        bool a = System.Convert.ToBoolean(values[0]);
        bool b = System.Convert.ToBoolean(values[1]);
        bool c = System.Convert.ToBoolean(values[2]);

        return !a && (b || !c);
    }
    ...
}

Di XAML saya menggunakan ini di MultiDataTriggerdalam <Style><Style.Triggers>sumber daya

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <!-- when the equation is TRUE ... -->
        <Condition Value="True">
            <Condition.Binding>
                <MultiBinding Converter="{StaticResource NOT_a_AND_P_b_OR_NOT_c_P}">
                    <!-- NOT IsFocus AND ( IsDefocused OR NOT Enabled ) -->
                    <Binding Path="IsFocus"/>
                    <Binding Path="IsDefocused" />
                    <Binding Path="Enabled" />
                </MultiBinding>
            </Condition.Binding>
        </Condition>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.Setters>
        <!-- ... show the 'dim-out' overlay -->
        <Setter Property="Visibility" Value="Visible" />
    </MultiDataTrigger.Setters>
</MultiDataTrigger>

Dan demi kelengkapan, konverter saya didefinisikan dalam a ResourceDictionary

<ResourceDictionary xmlns:conv="clr-namespace:My.Converters" ...>
    <conv:NOT_a_AND_P_b_OR_NOT_c_P x:Key="NOT_a_AND_P_b_OR_NOT_c_P" />
</ResourceDictionary>
cod3monk3y
sumber
11
Saya rasa ini bukan maksud konverter untuk digunakan dengan cara ini. Mereka benar-benar dimaksudkan untuk mengonversi nilai untuk tampilan. Ketika ini menjadi rumit, cukup buat properti terhitung pada model tampilan yang memberi Anda apa yang Anda butuhkan.
Martin Capodici
13
Namun penamaan itu
Kelly Elton
13
Harap luangkan waktu hening untuk mengingat saat pemrograman adalah keahlian dan kode anggun.
Fuzzy Logic
0

JAWABAN INI HANYA UNTUK ANIMASI


Jika Anda ingin menerapkan logika DAN, Anda harus menggunakan MultiTrigger, berikut ini sebuah contoh:

Misalkan kita ingin melakukan beberapa tindakan jika properti Text = "" (string kosong) DAN IsKeyboardFocused = "Salah", maka kode Anda akan terlihat seperti berikut:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <!-- Your actions here -->
        </MultiTrigger.EnterActions>
</MultiTrigger>

Jika Anda ingin menerapkan logika ATAU, ada beberapa cara, dan itu tergantung pada apa yang Anda coba lakukan:

Opsi pertama adalah menggunakan beberapa Pemicu.
Jadi, misalkan Anda ingin melakukan sesuatu jika salah Text = "" ATAU IsKeyboardFocused = "False",
maka kode Anda akan terlihat seperti ini:

<Trigger Property="IsEnabled" Value="false">
    <Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
    <Setter Property="BorderBrush" TargetName="border" 
            Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>


Tetapi masalah dalam hal ini adalah apa yang akan saya lakukan jika saya ingin melakukan sesuatu jika salah satu Teks TIDAK BAIK ATAU IsKeyboard = "Benar"? Ini dapat dicapai dengan pendekatan kedua:
Ingat aturan De Morgan, yang mengatakan! (! X &&! Y) = x || y.
Jadi kita akan menggunakannya untuk menyelesaikan masalah sebelumnya, dengan menulis multi pemicu yang dipicu ketika Text = "" dan IsKeyboard = "Benar", dan kami akan melakukan tindakan kami dalam TINDAKAN KELUAR , seperti ini:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.ExitActions>
        <!-- Do something here -->
    </MultiTrigger.ExitActions>
</MultiTrigger>
Elyasaf755
sumber