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?
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:
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>
@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.
conditionConverter
? Làm thế nào chúng ta chỉ định "Portland" và "HOẶC" là hai or
tùy chọn của chúng ta trong ví dụ này?
Để 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 IMultiValueConverter
tê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 MultiDataTrigger
trong 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>
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) VÀ 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>