Boolean CommandParameter trong XAML


76

Tôi có mã này (hoạt động vừa phải):

<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}">
    <KeyBinding.CommandParameter>
        <s:Boolean>
            True
        </s:Boolean>
    </KeyBinding.CommandParameter>
</KeyBinding>

Trong đó "s" tất nhiên là không gian tên Hệ thống.

Nhưng lệnh này được gọi khá nhiều lần và nó thực sự thổi phồng mã XAML khá đơn giản. Đây có thực sự là ký hiệu ngắn nhất của tham số lệnh boolean trong XAML (ngoài việc tách lệnh thành nhiều lệnh) không?

Câu trả lời:


110

Đây có thể là một chút hack nhưng bạn có thể lấy từ KeyBindinglớp:

public class BoolKeyBinding : KeyBinding
{
    public bool Parameter
    {
        get { return (bool)CommandParameter; }
        set { CommandParameter = value; }
    }
}

Sử dụng:

<local:BoolKeyBinding ... Parameter="True"/>

Và một giải pháp khác không quá kỳ lạ:

xmlns:s="clr-namespace:System;assembly=mscorlib"
<Application.Resources>
    <!-- ... -->
    <s:Boolean x:Key="True">True</s:Boolean>
    <s:Boolean x:Key="False">False</s:Boolean>
</Application.Resources>

Sử dụng:

<KeyBinding ... CommandParameter="{StaticResource True}"/>

Nó không chỉ dành cho KeyBindings, mà còn dành cho Buttons, v.v.
Matěj Zábský

Sau đó, những gì về phương pháp thứ hai của tôi mà tôi vừa thêm vào?
HB

1
Ý tưởng thú vị, điều đó đã không xảy ra với tôi. Tôi sẽ thử nó.
Matěj Zábský

@HB Tại sao của tôi luôn trả về false? Tôi không thể làm cho nó hoạt động.
Igor

3
@HB Câu trả lời tuyệt vời, có thể bạn có thể thêm điều này: xmlns:s="clr-namespace:System;assembly=mscorlib"vào câu trả lời của mình :)
BendEg

65

Đơn giản nhất là xác định những điều sau trong Tài nguyên

<System:Boolean x:Key="FalseValue">False</System:Boolean>
<System:Boolean x:Key="TrueValue">True</System:Boolean>

và sử dụng nó như:

<Button CommandParameter="{StaticResource FalseValue}"/>

5
và bạn cần thêm: xmlns:System="clr-namespace:System;assembly=mscorlib"vào quyền kiểm soát của người dùng
Alex

26

Hoặc, có thể là:

<Button.CommandParameter>
    <s:Boolean>True</s:Boolean>
</Button.CommandParameter>

Không gian tên ở đâu:

 xmlns:s="clr-namespace:System;assembly=mscorlib"

24

Tôi vừa tìm thấy một giải pháp chung chung hơn với tiện ích mở rộng đánh dấu này:

public class SystemTypeExtension : MarkupExtension
{
    private object parameter;

    public int Int{set { parameter = value; }}
    public double Double { set { parameter = value; } }
    public float Float { set { parameter = value; } }
    public bool Bool { set { parameter = value; } }
    // add more as needed here

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return parameter;
    }
}

Cách sử dụng ("wpf:" là không gian tên nơi tiện ích mở rộng nằm trong):

<KeyBinding Key="F8" Command="{Binding SomeCommand}" CommandParameter="{wpf:SystemType Bool=True}"/>

Bạn thậm chí có được các tùy chọn TrueFalsesau khi nhập Bool=và gõ an toàn!


@ marbel82 theo như tôi biết thì bạn có thể bỏ qua "Phần mở rộng" theo cách tương tự như "Thuộc tính" cho các thuộc tính. Cố gắng cho chính mình! Nhưng việc thêm tiện ích mở rộng tất nhiên sẽ không ảnh hưởng gì.
Onur

Onur, bạn đã đúng! Tôi không biết điều đó. Bạn nên viết thông tin này trong câu trả lời. Trước đây tôi đã kiểm tra mã của bạn, nhưng tôi đã gặp lỗi ở một nơi khác.
marbel82,

1
Đó là quá trơn, nó là bệnh. Cảm ơn giải pháp của bạn.
John Sully,

1
Chỉ cần tạo một markupextension mỗi loại (ví dụ BooleanExtension) và bạn có thể viết ví dụ CommandParameter={x:Boolean True}tương tự như docs.microsoft.com/en-us/dotnet/framework/xaml-services/...
Wouter

6

Có lẽ một cái gì đó giống như

<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}"
    CommandParameter="{x:Static StaticBoolean.True}" />

nơi StaticBoolean

public static class StaticBoolean
{
    public static bool True
    {
        get { return true; }
    }
}

Đúng. Giá trị được chuyển vào lệnh dưới dạng chuỗi (cũng không phải là những gì tôi muốn).
Matěj Zábský

Hmm, tôi sẽ sử dụng bộ chuyển đổi như thế nào trong ngữ cảnh này?
Matěj Zábský

Xin lỗi đã tìm thấy một cái gì đó đơn giản hơn.
Bala R

1
Đó là một sự tiến hóa thú vị mà tôi phải nói, đã thấy tất cả các bước: P Bây giờ nó xuống đến một tài nguyên bool (bạn cũng có thể làm trong Xaml, giống như trong câu trả lời của tôi)
HB

Tôi thực sự thích giải pháp của bạn. Tôi đề nghị một cải tiến nhỏ. Thay vì getchỉ cần khởi tạo một hằng số public static bool True = true;và thêm một hằng số khác public static bool False = false;.
marbel82,

1

Đây là một cách tiếp cận khác trong đó bạn xác định tiện ích mở rộng đánh dấu của riêng mình trả về Truehoặc False(hoặc bất kỳ giá trị nào khác mà bạn muốn). Sau đó, bạn chỉ cần sử dụng chúng ngay trong XAML giống như bất kỳ tiện ích mở rộng đánh dấu nào khác:

public class TrueExtension : MarkupExtension {
    public override object ProvideValue(IServiceProvider serviceProvider) => true;
}

public class FalseExtension : MarkupExtension {
    public override object ProvideValue(IServiceProvider serviceProvider) => false;
}

public class DoubleExtension : MarkupExtension {
    public DoubleExtension(){};
    public DoubleExtension(double value) => Value = value;
    public double Value { get; set; }
    public override object ProvideValue(IServiceProvider serviceProvider) => Value;
}

Sau đó, bạn sử dụng chúng như thế này (giả sử không gian tên đã nhập của bạn là mx):

<KeyBinding Key="Enter"
    Command="{Binding ReturnResultCommand}"
    CommandParameter="{mx:True}" />

<Button Visibility="{Binding SomeProperty,
    Converter={SomeBoolConverter},
    ConverterParameter={mx:True}}">

<!-- This guarantees the value passed is a double equal to 42.5 -->
<Button Visibility="{Binding SomeProperty,
    Converter={SomeDoubleConverter},
    ConverterParameter={mx:Double 42.5}}">

Tôi thực sự xác định rất nhiều MarkupExtensionlớp tùy chỉnh cho nhiều thứ phổ biến mà tôi không muốn nhất thiết phải lưu trữ trong tài nguyên của mình.

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.