จะส่งจำนวนเต็มเป็น ConverterParameter ได้อย่างไร


95

ฉันกำลังพยายามเชื่อมโยงกับคุณสมบัติจำนวนเต็ม:

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

และตัวแปลงของฉันคือ:

[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;
    }
}

ปัญหาคือเมื่อตัวแปลงของฉันเรียกว่าพารามิเตอร์เป็นสตริง ฉันต้องการให้เป็นจำนวนเต็ม แน่นอนฉันสามารถแยกวิเคราะห์สตริงได้ แต่ฉันต้องทำอย่างไร

ขอบคุณสำหรับความช่วยเหลือของคอนสแตนติน


2
มีใครรู้วิธีทำสิ่งนี้บนแพลตฟอร์ม Windows Phone ที่เรามีไวยากรณ์ที่แตกต่างกันเล็กน้อยสำหรับการผูกไหม {Binding PROPERTY, Converter = {StaticResource MYCONVERTER}, ConverterParameter = INT_VAL} ในตัวอย่างนี้ INT_VAL จะถูกส่งผ่านเป็นสตริง
Krzysztof Kaczor

คำตอบ:


107

จัดไป!

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

เคล็ดลับคือการรวมเนมสเปซสำหรับประเภทระบบพื้นฐานจากนั้นเขียนอย่างน้อยการผูก ConverterParameter ในรูปแบบองค์ประกอบ


2
นี้ไม่ได้เปลี่ยนแปลงความจริงที่ว่าประเภทของIValueConverter.Convert()'s 'พารามิเตอร์'objectพารามิเตอร์ คุณยังต้องแคสต์ / แยกวิเคราะห์ ...
Dan J

6
@djacobson - จริง แต่นั่นคือสิ่งที่แอตทริบิวต์ ValueConversion อนุญาตให้คุณระบุ ไม่แน่ใจว่าสิ่งนี้ถูกใช้ในเวลาคอมไพล์หรือรันไทม์จริงๆ ในแง่ของคำถามผู้โพสต์ต้นฉบับเขาระบุว่า "ฉันต้องการให้เป็นจำนวนเต็มแน่นอนฉันสามารถแยกวิเคราะห์สตริงได้ แต่ฉันต้องทำอย่างไร" ดังนั้นคำตอบของฉันจึงช่วยบรรเทาว่าในนั้นไม่มีการแยกวิเคราะห์สตริง แต่มีเพียงการแกะกล่องจำนวนเต็มซึ่งฉันยังปลอดภัยกว่ามาก
jpierson

51

เพื่อความสมบูรณ์อีกวิธีหนึ่งที่เป็นไปได้ (อาจพิมพ์น้อยลง):

<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}}" />

(แน่นอนว่าWindowสามารถแทนที่ได้UserControlและIntZeroอาจกำหนดให้ใกล้เคียงกับสถานที่ใช้งานจริงมากขึ้น)


45

ไม่แน่ใจว่าทำไมคนมีแนวโน้มที่จะอิดออดต่อการใช้WPF MarkupExtensionเป็นทางออกที่สมบูรณ์แบบสำหรับปัญหาต่างๆรวมถึงปัญหาที่กล่าวถึงที่นี่

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

หากส่วนขยายมาร์กอัปนี้มีอยู่ในXAMLเนมสเปซ "m" ตัวอย่างของผู้โพสต์ต้นฉบับจะกลายเป็น:

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

สิ่งนี้ใช้งานได้เนื่องจากตัวแยกวิเคราะห์ส่วนขยายมาร์กอัปสามารถเห็นชนิดที่แข็งแกร่งของอาร์กิวเมนต์ตัวสร้างและแปลงตามนั้นในขณะที่อาร์กิวเมนต์ ConverterParameter ของ Binding คือ Object-typed


ขอบคุณสิ่งนี้มีประโยชน์ มันจะเป็นนามสกุล XAML แรกของฉัน แต่ผมคิดว่ามันจะดีกว่าที่จะทำให้มากกว่าเพื่อหลีกเลี่ยงมวยแต่ละครั้งใน (จากนั้นให้หลีกเลี่ยงการมอบหมายสิ่งที่ผิดกฎหมายโดยตรง) ValueobjectintProvideValueprivate
Zeus

1
@Zeus โดยปกติProvideValueจะเรียกเพียงครั้งเดียวต่ออินสแตนซ์ส่วนขยายมาร์กอัปดังนั้นการชกมวยควรเกิดขึ้นเพียงครั้งเดียวเท่านั้น โดยไม่ทำในคอนสตรัคเตอร์ฉันจะหลีกเลี่ยงการชกมวยโดยสิ้นเชิงหากProvideValueไม่เคยถูกเรียก สำหรับการทำให้เป็นValueส่วนตัวสิ่งนี้จะป้องกันไม่ให้ใช้ส่วนขยายมาร์กอัปในXAMLไวยากรณ์ขององค์ประกอบวัตถุ: msdn.microsoft.com/en-us/library/…
Glenn Slayden

ย่อหน้าสุดท้ายของคุณไม่ถูกต้อง เรียกว่าการแปลงประเภทและยังใช้กับคุณสมบัติ สิ่งนี้คือBinding.ConverterParameterไม่มีประเภทที่เฉพาะเจาะจง (เป็นเพียงแค่ an object) ดังนั้นตัวแยกวิเคราะห์จึงไม่ทราบว่าจะใช้การแปลงใดดังนั้นตัวอักษรทุกตัวจะถือว่าเป็นสตริงเท่านั้น
HB

(ดังนั้นหากส่วนขยายของคุณมีตัวสร้างเริ่มต้นก็{m:Int32 Value=0}จะใช้งานได้เช่นกัน)
HB


0

มันเป็นการดีที่จะแสดงข้อมูลประเภทของ ConverterValue ใน XAML แต่ฉันไม่คิดว่าจะเป็นไปได้ในตอนนี้ ดังนั้นฉันเดาว่าคุณต้องแยกวิเคราะห์วัตถุตัวแปลงเป็นประเภทที่คุณคาดหวังด้วยตรรกะที่กำหนดเอง ฉันไม่เห็นทางอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.