ตั้งค่าเป็น null ในการผูก WPF


116

โปรดดูที่บรรทัดต่อไปนี้

<TextBox Text="{Binding Price}"/>

พร็อพเพอร์ตี้ Price จากด้านบนนี้เป็นDecimal?(ทศนิยมที่เป็นNullable)

ฉันต้องการให้หากผู้ใช้ลบเนื้อหาของกล่องข้อความ (เช่นป้อนสตริงว่างควรอัปเดตซอร์สโดยอัตโนมัติด้วย null (ไม่มีอะไรใน VB)

มีความคิดเห็นเกี่ยวกับวิธีทำ 'Xamly' บ้างไหม?

คำตอบ:


226

ฉันใช้. NET 3.5 SP1 ดังนั้นมันง่ายมาก:

<TextBox Text="{Binding Price, TargetNullValue=''}"/>

ซึ่งย่อมาจาก (ขอบคุณ Gregor สำหรับความคิดเห็นของคุณ):

<TextBox Text="{Binding Price, TargetNullValue={x:Static sys:String.Empty}}"/>

sysคือเนมสเปซ xml ที่นำเข้าสำหรับSystemในmscorlib:

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

หวังว่าจะช่วยได้


13
จริงๆแล้ว TargetNullValue ใช้งานได้ดี สิ่งที่ตั้งค่าความเท่าเทียมกันระหว่างค่าที่กำหนดและค่าว่าง ดังนั้นในกรณีนี้เมื่อค่าที่ถูกผูกไว้เป็นค่าว่างระบบจะแสดงสตริงว่างและเมื่อค่าของเป้าหมายเป็นสตริงว่างก็จะตั้งค่าที่ถูกผูกไว้เป็น null
Bryan Anderson

4
TargetNullValue ใช้งานได้ ฉันได้ผลลัพธ์เดียวกันเมื่อใช้ตัวแปลงค่า คุณยังสามารถลดความซับซ้อนของนิพจน์: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec

2
ฉันสับสน - OP พูดว่า: ".. ควรอัปเดตซอร์สโดยอัตโนมัติด้วย null [เมื่อ Target เป็นสตริงว่าง]" แต่ TargetNullValue อัปเดตTargetไม่ใช่Source !
markmnl

1
คุณไม่ใช่คนเดียวที่สับสน แต่ยังมีความคิดเห็นที่สับสนในคำตอบอื่นด้วย OP ยังสับสนเล็กน้อยเมื่อเขาพูดว่าอัปเดตแหล่งที่มาเขาหมายถึง Target ใน WPF speak (แหล่งที่มาคือคุณสมบัติ Text บน TextBox) TargetNullValue บอกว่าจะตั้งค่า Source เป็นค่าใดเมื่อ Target เป็นโมฆะ สิ่งที่ตรงกันข้ามซึ่งเป็นสิ่งที่เราใช้ประโยชน์จากที่นี่คือเมื่อแหล่งที่มาถูกอัปเดตเป็นค่าที่ระบุนี้เป้าหมายจะถูกตั้งค่าเป็นโมฆะ
Nathan Phillips

@markmnl ในขณะที่ TargetNullValue มีวัตถุประสงค์เพื่ออัปเดตTargetและไม่ใช่Sourceโซลูชันนี้ยังคงใช้เคล็ดลับด้วยเหตุผลบางประการ (ฉันไม่สามารถเข้าใจได้ว่าทำไม)
Tim Pohlmann

12

ตัวแปลงค่านี้ควรทำเคล็ดลับ:

public class StringToNullableDecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        CultureInfo culture)
    {
        decimal? d = (decimal?)value;
        if (d.HasValue)
            return d.Value.ToString(culture);
        else
            return String.Empty;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        string s = (string)value;
        if (String.IsNullOrEmpty(s))
            return null;
        else
            return (decimal?)decimal.Parse(s, culture);
    }
}

ประกาศอินสแตนซ์ของตัวแปลงนี้ในแหล่งข้อมูล:

<Window.Resources>
    <local:StringToNullableDecimalConverter x:Key="nullDecimalConv"/>
</Window.Resources>

และใช้ในการผูกของคุณ:

<TextBox Text="{Binding Price, Converter={StaticResource nullDecimalConv}}"/>

โปรดทราบว่าTargetNullValueไม่เหมาะสมที่นี่: ใช้เพื่อกำหนดว่าควรใช้ค่าใดเมื่อsourceการเชื่อมโยงเป็นโมฆะ ที่นี่Priceไม่ใช่แหล่งที่มา แต่เป็นสมบัติของแหล่ง ...


2
ตัวแปลงเป็นวิธีที่เหมาะสมในการดำเนินการนี้และคุณไม่สามารถกำหนดตัวแปลงเหล่านี้ใน XAML ได้ ตัวแปลงช่วยให้คุณเปลี่ยนพฤติกรรมการแปลง "object to object" ที่เป็นค่าเริ่มต้นในการเชื่อมโยงข้อมูลซึ่งเป็นสิ่งที่คุณต้องการทำ
Will Eddins

ปัญหาในกรณีของฉันคือฉันใช้คอนเวอร์เรเตอร์ตรงนี้ซึ่งทำอย่างอื่นอยู่แล้ว ฉันโพสต์คำตอบโปรดดู
Shimmy Weitzhandler

อาจต้องการใช้ IsNullOrWhiteSpace () เพื่อให้ "" ถูกนับเป็นโมฆะ (ส่วนใหญ่อาจเป็นสิ่งที่คุณต้องการ)
Simon_Weaver

+1 อย่างไรก็ตาม: ราคาเป็นแหล่งที่มาของคุณที่นี่ แต่คุณถูกต้อง TargetNullValue ไม่เหมาะสมที่นี่ - TargetNullValue ตั้งค่าเป้าหมายเมื่อแหล่งที่มาเป็นโมฆะ - ในขณะที่เราต้องการกำหนดแหล่งที่มา (เป็น null) เมื่อเป้าหมายเป็นค่าที่แน่นอน (ค่าว่าง สตริง) - ซึ่งตัวแปลงของคุณทำ
markmnl

5

คุณสามารถลองใช้ ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

ที่ด้านหลังศีรษะของฉันที่นี่มีบางอย่างเช่น:

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return (double)value;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
    var doubleValue = Convert.ToDouble(value);

    return (doubleValue == 0 ? null : doubleValue);
    }
}

(อาจต้องปรับแต่งบ้าง)


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