làm thế nào để chuyển một số nguyên dưới dạng ConverterParameter?


95

Tôi đang cố gắng liên kết với một thuộc tính số nguyên:

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter=0}" />

và công cụ chuyển đổi của tôi là:

[ValueConversion(typeof(int), typeof(bool))]
public class IntToBoolConverter : IValueConverter
{
    public object Convert(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
    }
}

vấn đề là khi bộ chuyển đổi của tôi được gọi là tham số là chuỗi. tôi cần nó là một số nguyên. tất nhiên tôi có thể phân tích cú pháp chuỗi, nhưng tôi có phải làm vậy không?

cảm ơn vì bất kỳ sự giúp đỡ nào konstantin


2
Có ai biết cách thực hiện điều này trên nền tảng Windows Phone, nơi chúng tôi có cú pháp hơi khác cho các ràng buộc không? {Binding PROPERTY, Converter = {StaticResource MYCONVERTER}, ConverterParameter = INT_VAL} trong ví dụ này INT_VAL sẽ được chuyển dưới dạng một chuỗi
Krzysztof Kaczor

Câu trả lời:


106

Đây rồi!

<RadioButton Content="None"
             xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <RadioButton.IsChecked>
        <Binding Path="MyProperty"
                 Converter="{StaticResource IntToBoolConverter}">
            <Binding.ConverterParameter>
                <sys:Int32>0</sys:Int32>
            </Binding.ConverterParameter>
        </Binding>
    </RadioButton.IsChecked>
</RadioButton>

Bí quyết là bao gồm không gian tên cho các loại hệ thống cơ bản và sau đó viết ít nhất liên kết ConverterParameter ở dạng phần tử.


2
Điều này không thay đổi một thực tế là loại IValueConverter.Convert()'s 'thông số' tham số là object. Bạn vẫn phải truyền / phân tích cú pháp nó ...
Dan J

6
@djacobson - Đúng nhưng đó là những gì thuộc tính ValueConversion cho phép bạn chỉ định. Không chắc chắn liệu điều này có thực sự được sử dụng trong thời gian biên dịch hay thời gian chạy hay không. Về câu hỏi của người đăng ban đầu, anh ấy chỉ rõ rằng "tôi cần nó là một số nguyên. Tất nhiên tôi có thể phân tích cú pháp chuỗi, nhưng tôi có phải làm vậy không?" Vì vậy, câu trả lời của tôi làm giảm bớt điều đó trong đó không có phân tích cú pháp của một chuỗi mà chỉ có sự mở hộp của một số nguyên mà tôi vẫn an toàn hơn nhiều.
jpierson

51

Để có sự hoàn chỉnh, một giải pháp khả thi hơn (có lẽ với ít đánh máy hơn):

<Window
    xmlns:sys="clr-namespace:System;assembly=mscorlib" ...>
    <Window.Resources>
        <sys:Int32 x:Key="IntZero">0</sys:Int32>
    </Window.Resources>

    <RadioButton Content="None"
                 IsChecked="{Binding MyProperty,
                                     Converter={StaticResource IntToBoolConverter},
                                     ConverterParameter={StaticResource IntZero}}" />

(Tất nhiên, Windowcó thể được thay thế bằng UserControl, và IntZerocó thể được xác định gần hơn với nơi sử dụng thực tế.)


44

Không chắc tại sao WPFmọi người có xu hướng không thích sử dụng MarkupExtension. Nó là giải pháp hoàn hảo cho nhiều vấn đề bao gồm cả vấn đề được đề cập ở đây.

public sealed class Int32Extension : MarkupExtension
{
    public Int32Extension(int value) { this.Value = value; }
    public int Value { get; set; }
    public override Object ProvideValue(IServiceProvider sp) { return Value; }
};

Nếu phần mở rộng đánh dấu này có sẵn trong XAMLkhông gian tên 'm', thì ví dụ của người đăng ban đầu sẽ trở thành:

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter={m:Int32 0}}" />

Điều này hoạt động vì trình phân tích cú pháp của phần mở rộng đánh dấu có thể thấy kiểu mạnh của đối số phương thức khởi tạo và chuyển đổi tương ứng, trong khi đối số ConverterParameter của Binding là kiểu đối tượng (ít thông tin).


Cảm ơn, điều đó rất hữu ích. Nó sẽ là phần mở rộng XAML đầu tiên của tôi. Nhưng tôi nghĩ tốt hơn là nên kiếm Valuemột cái objecthơn là inttránh đấm bốc nó mỗi lần vào ProvideValue. (Và sau đó, làm cho nó privateđể tránh chỉ định một cái gì đó bất hợp pháp trực tiếp).
Zeus vào

1
@Zeus Thông thường ProvideValuechỉ được gọi một lần cho mỗi phiên bản tiện ích mở rộng đánh dấu, vì vậy dù sao thì quyền anh cũng chỉ xảy ra một lần. Bằng cách không thực hiện nó trong hàm tạo, tôi tránh hoàn toàn quyền anh nếu ProvideValuekhông bao giờ được gọi. Đối với việc đặt ở chế độ Valueriêng tư, điều này sẽ loại trừ việc sử dụng tiện ích mở rộng đánh dấu trong XAMLcú pháp phần tử đối tượng: msdn.microsoft.com/en-us/library/…
Glenn Slayden

Đoạn cuối của bạn là sai. Nó được gọi là chuyển đổi kiểu và nó cũng áp dụng cho các thuộc tính. Vấn đề là, Binding.ConverterParameterkhông có kiểu cụ thể (nó chỉ là một object) nên trình phân tích cú pháp không biết chuyển đổi nào để áp dụng, do đó mọi ký tự chỉ được coi như một chuỗi.
HB

(Vì vậy, nếu tiện ích mở rộng của bạn có một hàm tạo mặc định, thì {m:Int32 Value=0}nó cũng sẽ hoạt động.)
HB

5

Không sử dụng value.Equals. Sử dụng:

  Convert.ToInt32(value) == Convert.ToInt32(parameter)

8
Tại sao bạn không muốn sử dụng value.Equals?
Zack

1

Sẽ rất tuyệt nếu bằng cách nào đó thể hiện thông tin loại cho ConverterValue trong XAML, nhưng tôi không nghĩ rằng nó có thể xảy ra ngay bây giờ. Vì vậy, tôi đoán bạn phải phân tích cú pháp Đối tượng chuyển đổi thành loại mong đợi của bạn bằng một số logic tùy chỉnh. Tôi không thấy cách nào khác.

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.