Làm cách nào tôi có thể cung cấp nhiều điều kiện để kích hoạt dữ liệu trong WPF?


173

Làm cách nào tôi có thể cung cấp nhiều điều kiện để kích hoạt dữ liệu trong WPF?

Câu trả lời:


280

Sử dụng loại 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
Có cách nào để thực hiện một câu lệnh "HOẶC" trong multiTrigger. ví dụ: tên = "portland" HOẶC nhà nước = "HOẶC"
jasonk

12
@jasonk - Không chắc chắn nếu bạn có thể làm điều đó với MultiTrigger. Bạn có thể xác định hai kích hoạt cho điều đó ..
Gishu

2
Nếu đó là một câu lệnh điều kiện OR đơn giản, bạn có thể đảo ngược logic để nó biến thành AND. | điều kiện1 | điều kiện2 | kết quả | | đúng | đúng | đúng | | đúng | sai | đúng | | sai | đúng | đúng | | sai | sai | sai | thay vì kiểm tra / OR là đúng, hãy kiểm tra khi cả hai / AND đều sai và đặt mặc định thành true.
WeSam Abdallah

3
@WeSamAbdallah Bạn không thể kiểm tra các điều kiện là sai.
Jim Balter

4
Bạn có thể kiểm tra một điều kiện là sai bởi một trình chuyển đổi đơn giản.
Paul

50

@jasonk - nếu bạn muốn có "hoặc" thì phủ nhận tất cả các điều kiện vì (A và B) <=> ~ (~ A hoặc ~ B)

nhưng nếu bạn có các giá trị khác ngoài boolean, hãy thử sử dụng trình chuyển đổi kiểu:

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

bạn có thể sử dụng các giá trị trong phương thức Convert theo bất kỳ cách nào bạn muốn để tạo ra một điều kiện phù hợp với bạn.


3
Ah, di chuyển thông minh để phủ nhận mọi thứ và lật nó sang điều kiện OR :)
myermian

8
Bạn có thể vui lòng mở rộng câu trả lời này một chút không? Tôi không chắc làm thế nào để sử dụng nó. Làm gì conditionConverter? Làm thế nào chúng ta chỉ định "Portland" và "HOẶC" là hai ortùy chọn của chúng ta trong ví dụ này?
DLeh

4
@ cod3monk3y, liên kết của bạn bị hỏng.
Spidermain50

22

Để giải thích câu trả lời của @ serine và minh họa làm việc với điều kiện đa giá trị không tầm thường: Tôi có nhu cầu hiển thị lớp phủ "mờ" trên một mục cho điều kiện boolean NOT a AND (b OR NOT c).

Đối với nền, đây là một câu hỏi "Nhiều lựa chọn". Nếu người dùng chọn một câu trả lời sai, nó sẽ bị vô hiệu hóa ( bị mờ đi và không thể được chọn lại). Một tác nhân tự động có khả năng tập trung vào bất kỳ lựa chọn cụ thể nào để đưa ra lời giải thích (đường viền được tô sáng). Khi tác nhân tập trung vào một vật phẩm, nó không nên bị mờ đi ngay cả khi nó bị vô hiệu hóa . Tất cả các mục không tập trung được đánh dấu không tập trung và nên được làm mờ đi.

Do đó, logic để làm mờ là:

NOT IsFocused AND (IsDefocused OR NOT Enabled)

Để thực hiện logic này, tôi đã tạo một IMultiValueConvertertên chung (lúng túng) để khớp với logic của tôi

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

Trong XAML tôi sử dụng điều này MultiDataTriggertrong một <Style><Style.Triggers>tài nguyên

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

Và để hoàn thiện, bộ chuyển đổi của tôi được định nghĩa trong một 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
Tôi không nghĩ rằng đây là mục đích của các bộ chuyển đổi sẽ được sử dụng theo cách này. Chúng thực sự có nghĩa là để chuyển đổi giá trị để hiển thị. Khi nó trở nên phức tạp, chỉ cần tạo một thuộc tính được tính toán trên mô hình khung nhìn cung cấp cho bạn những gì bạn cần.
Martin Capodici

13
Việc đặt tên đó mặc dù
Kelly Elton

13
Xin vui lòng dành một chút thời gian im lặng để nhớ khi lập trình là một nghề thủ công và mã là thanh lịch.
Logic mờ

0

TRẢ LỜI NÀY CHỈ DÀNH CHO ĐỘNG


VẬT Nếu bạn muốn triển khai logic AND, bạn nên sử dụng MultiTrigger, đây là một ví dụ:

Giả sử chúng tôi muốn thực hiện một số hành động nếu thuộc tính Text = "" (chuỗi trống) IsPalF Focused = "Sai", sau đó mã của bạn sẽ trông như sau:

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

Nếu bạn muốn triển khai logic OR, có một số cách và nó phụ thuộc vào những gì bạn cố gắng thực hiện:

Tùy chọn đầu tiên là sử dụng nhiều Triggers.
Vì vậy, giả sử bạn muốn làm một cái gì đó nếu Text = "" HOẶC IsPalF Focused = "Sai",
thì mã của bạn sẽ trông giống như thế này:

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


Nhưng vấn đề ở đây là tôi sẽ làm gì nếu tôi muốn làm gì đó nếu Văn bản KHÔNG NÊN HOẶC IsPal = "Đúng"? Điều này có thể đạt được bằng cách tiếp cận thứ hai:
Nhớ lại quy tắc của De Morgan, nghĩa là! (! X &&! Y) = x || y.
Vì vậy, chúng tôi sẽ sử dụng nó để giải quyết vấn đề trước đó, bằng cách viết một trình kích hoạt đa kích hoạt khi Text = "" và IsPal = "True" và chúng tôi sẽ thực hiện các hành động của mình trong EXIT ACTION , như thế này:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="Text" Value="" />
        <Condition Property="IsKeyboardFocused" Value="False" />
    </MultiTrigger.Conditions>
    <MultiTrigger.ExitActions>
        <!-- Do something here -->
    </MultiTrigger.ExitActions>
</MultiTrigger>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.