ฉันจะระบุเงื่อนไขหลายอย่างสำหรับทริกเกอร์ข้อมูลใน WPF ได้อย่างไร


173

ฉันจะระบุเงื่อนไขหลายอย่างสำหรับทริกเกอร์ข้อมูลใน WPF ได้อย่างไร

คำตอบ:


280

ใช้ประเภท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>

28
มีวิธีการทำคำสั่ง "หรือ" ใน multiTrigger เช่นชื่อ = "พอร์ตแลนด์" หรือรัฐ = "หรือ"
jasonk

12
@jasonk - ไม่แน่ใจว่าคุณสามารถทำได้ด้วย MultiTrigger คุณสามารถกำหนดทริกเกอร์สองตัวสำหรับ ..
Gishu

2
ถ้ามันเป็นคำสั่งง่าย ๆ หรือเงื่อนไขคุณสามารถย้อนกลับตรรกะเพื่อเปลี่ยนเป็น AND | เงื่อนไข 1 | เงื่อนไข 2 | ผลลัพธ์ | | จริง | จริง | จริง | | จริง | เท็จ | จริง | | เท็จ | จริง | จริง | | เท็จ | เท็จ | เท็จ | แทนที่จะตรวจสอบว่า / หรือเป็นจริงให้ตรวจสอบว่าทั้ง / และเป็นเท็จและตั้งค่าเริ่มต้นเป็นจริง
WeSam Abdallah

3
@WeSamAbdallah คุณไม่สามารถตรวจสอบเงื่อนไขที่ผิดพลาดได้
Jim Balter

4
คุณสามารถตรวจสอบเงื่อนไขที่เป็นเท็จได้โดยตัวแปลงอย่างง่าย
เปาโล

50

@jasonk - หากคุณต้องการมี "หรือ" ให้ปฏิเสธเงื่อนไขทั้งหมดตั้งแต่ (A และ B) <=> ~ (~ A หรือ ~ B)

แต่ถ้าคุณมีค่าอื่นที่ไม่ใช่บูลีนลองใช้ตัวแปลงชนิด:

<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>

คุณสามารถใช้ค่าในวิธีการแปลงในแบบที่คุณต้องการในการสร้างเงื่อนไขที่เหมาะสมกับคุณ


3
อามาร์ทย้ายทุกอย่างลบล้างและพลิกไปยังหรือสภาพ :)
myermian

8
คุณช่วยขยายคำตอบนี้หน่อยได้ไหม? ฉันไม่แน่ใจว่าจะใช้มันอย่างไร อะไรconditionConverterทำอย่างไร เราจะระบุ "พอร์ตแลนด์" และ "หรือ" เป็นสองorตัวเลือกในตัวอย่างนี้ได้อย่างไร
DLeh

4
@ cod3monk3y ลิงก์ของคุณเสีย
Spidermain50

22

การทำอย่างละเอียดใน@ คำตอบซีรีส์และแสดงให้เห็นถึงการทำงานร่วมกับเงื่อนไขหลายมูลค่าไม่น่ารำคาญ: ผมมีความจำเป็นที่จะต้องแสดง "สลัวออก" NOT a AND (b OR NOT c)ซ้อนทับในรายการสำหรับสภาพแบบบูล

สำหรับพื้นหลังนี่เป็นคำถาม "หลายตัวเลือก" หากผู้ใช้เลือกคำตอบที่ผิดมันจะปิดการใช้งาน (จางลงและไม่สามารถเลือกได้อีกครั้ง) ตัวแทนอัตโนมัติมีความสามารถในการมุ่งเน้นไปที่ตัวเลือกใด ๆ เพื่อให้คำอธิบาย (เน้นที่เส้นขอบ) เมื่อตัวแทนมุ่งเน้นไปที่รายการที่มันไม่ควรจะเป็นสีจางออกแม้ว่าจะเป็นคนพิการ รายการทั้งหมดที่ไม่ได้อยู่ในโฟกัสจะถูกทำเครื่องหมายแบบไม่โฟกัสและควรจางลง

ตรรกะสำหรับการหรี่แสงคือ:

NOT IsFocused AND (IsDefocused OR NOT Enabled)

ในการใช้ตรรกะนี้ฉันสร้างIMultiValueConverterชื่อสามัญ(อย่างเชื่องช้า) เพื่อจับคู่ตรรกะของฉัน

// '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);
    }
    ...
}

ใน XAML ฉันจะใช้นี้ในMultiDataTriggerใน<Style><Style.Triggers>ทรัพยากร

<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>

และเพื่อความสมบูรณ์ตัวแปลงของฉันถูกกำหนดใน 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>

11
ฉันไม่คิดว่านี่เป็นเจตนาของผู้ที่จะใช้วิธีนี้ พวกเขามีความหมายจริงๆสำหรับการแปลงค่าสำหรับการแสดงผล เมื่อมันซับซ้อนนี้เพียงแค่สร้างคุณสมบัติที่คำนวณได้ในโมเดลมุมมองที่ให้สิ่งที่คุณต้องการ
Martin Capodici

13
แม้ว่าการตั้งชื่อนั้น
Kelly Elton

13
โปรดสละเวลาสักครู่ในการจำเมื่อการเขียนโปรแกรมเป็นงานฝีมือและรหัสนั้นสวยงาม
Fuzzy Logic

0

คำตอบนี้มีไว้สำหรับภาพเคลื่อนไหวเท่านั้น


หากคุณต้องการใช้ AND และตรรกะคุณควรใช้ MultiTrigger ต่อไปนี้เป็นตัวอย่าง:

สมมติว่าเราต้องการดำเนินการบางอย่างถ้าคุณสมบัติ Text = "" (สตริงว่าง) และ IsKeyboardFocused = "False" รหัสของคุณควรมีลักษณะดังนี้:

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

หากคุณต้องการใช้ตรรกะ OR มีหลายวิธีขึ้นอยู่กับสิ่งที่คุณพยายามทำ:

ตัวเลือกแรกคือใช้ทริกเกอร์หลายตัว
ดังนั้นสมมติว่าคุณต้องการทำอะไรถ้า Text = "" หรือ IsKeyboardFocused = "False"
รหัสของคุณควรมีลักษณะดังนี้:

<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>


แต่ปัญหาในนี่คือสิ่งที่ฉันจะทำถ้าฉันต้องการที่จะทำอะไรถ้าอย่างใดอย่างหนึ่งข้อความไม่ว่างหรือ IsKeyboard = "จริง"? สิ่งนี้สามารถทำได้โดยวิธีที่สอง:
กฎของ Recall De Morgan, ที่บอกว่า! (! x &&! y) = x || Y
ดังนั้นเราจะใช้มันเพื่อแก้ปัญหาก่อนหน้านี้โดยการเขียนทริกเกอร์หลายตัวที่มันถูกเรียกเมื่อ Text = "" และ IsKeyboard = "True" และเราจะดำเนินการในEXIT ACTIONSดังนี้:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.ExitActions>
        <!-- Do something here -->
    </MultiTrigger.ExitActions>
</MultiTrigger>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.