2017-06-07 31 views
0

嗯,WPF這個小怪癖真的在我的皮膚下。所以,我有一個DataGrid這樣的:綁定到WPF中的可空數據類型

<DataGrid x:Name="Rates" AlternatingRowBackground="#FCFCFC" AutoGenerateColumns="False" CanUserReorderColumns="True" CanUserResizeColumns="True" CanUserAddRows="False" SelectionUnit="FullRow" CanUserSortColumns="True"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Item" Width="Auto" IsReadOnly="True" Binding="{Binding item}"/> 
     <DataGridTextColumn Header="Rate" Width ="*" Binding="{Binding rate, UpdateSourceTrigger=PropertyChanged}"/> 
    </DataGrid.Columns> 

它只是在A列的項目清單,我們必須進入B列聽起來很簡單的費率。

以下是它綁定到的ViewModel中的屬性。

private BindableCollection<Rate> _rates; 

public BindableCollection<Rate> Rates 
{ 
    get 
    { 
     return _rates; 
    } 

    set 
    { 
     if (value == _rates) 
     { 
      return; 
     } 

     _rates = value; 
     NotifyOfPropertyChange(); 
    } 
} 

這裏是Rate定義:

public partial class Rate 
{ 
    public int ID { get; set; } 
    public string client { get; set; } 
    public string item { get; set; } 
    public Nullable<decimal> rate { get; set; } 
} 

所以,我DataGrid的第二列是越來越勢必Rate.rate這是一個Nullable<decimal>。這就是問題所在。 Nullable<decimal>確實接受NULL,但TextBox不會讓我輸入空白值。此外,如果我鍵入某個值,然後將其刪除,那麼ViewModel將保留先前的值。

我已經看到涉及IValueConverter的解決方案,但我更喜歡基於XAML的解決方案。有沒有?我有幾個模塊,其中DataTypeNullable,如果每次都必須使用IValueConverter,它會很快變得非常單調乏味。

編輯

我使用Caliburn.Micro,因此使用TargetNullValue=''不會工作無處不在,作爲綁定是自動的。它將在上面的示例中工作,其中明確提到了binding

+0

一個黑客可以用字符串替換Nullable decimal,然後驗證用戶輸入,甚至限制用戶輸入只允許通過擴展文本框類文本更改事件或previewKeydown事件來允許十進制值。 –

回答

2

如果您正在使用Caliburn.Micro,您可以配置CM方式適用於您查看和您的視圖模型之間的自動綁定。

所以在你Bootstrapper CLASSE的Configure方法,你可以寫類似:

protected override void Configure() 
{ 
    ConventionManager.SetBinding = delegate(Type viewModelType, string path, PropertyInfo property, FrameworkElement element, ElementConvention convention, DependencyProperty bindableProperty) 
    { 
     Binding binding = new Binding(path); 
     ConventionManager.ApplyBindingMode(binding, property); 
     ConventionManager.ApplyValueConverter(binding, bindableProperty, property); 
     ConventionManager.ApplyStringFormat(binding, convention, property); 
     ConventionManager.ApplyValidation(binding, viewModelType, property); 
     ConventionManager.ApplyUpdateSourceTrigger(bindableProperty, element, binding, property); 

     if (Nullable.GetUnderlyingType(property.PropertyType) != null) 
     { 
      binding.TargetNullValue = String.Empty; 
     } 

     BindingOperations.SetBinding(element, bindableProperty, binding); 
    }; 

    // Your own configurations... 
} 

正如你可以看到這個代碼將BindingTargetNullValue財產,如果源屬性爲Nullable。它適用於CM在您的應用程序中爲您創建的所有自動綁定。

我希望它有幫助。

編輯

關於你的最後的評論,認爲卡利微不處理這已經綁定(在XAML)FrameworkElement s至物業時適用的「自動綁定」。

所以,如果你想自動設置您的「手動」綁定的TargetNullValue,井simpliest想法是創建自己的綁定:

public class NullableBinding : Binding 
{ 
    public NullableBinding(string path) 
     : base(path) 
    { 
     TargetNullValue = String.Empty; 
    } 

    public NullableBinding() 
     : base() 
    { 
     TargetNullValue = String.Empty; 
    } 
} 

,然後在XAML中使用它:

<DataGridTextColumn Header="Rate" Width ="*" Binding="{local:NullableBinding rate}"/> 
+1

它的確如此。 https://github.com/Caliburn-Micro/Caliburn.Micro/issues/448的官方答覆沒有。即使當我將'type'改爲'GetType()'。 –

+0

好吧,修改代碼,最後這是工作: 'var existingApplyValidation = ConventionManager.ApplyValidation; ConventionManager.ApplyValidation =(binding,viewModelType,property)=> {0} {0} {0} existingApplyValidation(binding,viewModelType,property); //保留現有行爲 if(Nullable.GetUnderlyingType(property.PropertyType)!= null) binding.TargetNullValue = String.Empty; };' 您的代碼有幫助。從你的代碼中複製了條件語句。 –

+0

我正在測試這個解決方案,它只適用於Caliburn.Micro自動綁定元素的地方。例如它在這裏工作:''。但是在手動定義綁定的地方不起作用,如:'。我們可以通過任何方式爲應用程序範圍的綁定設置默認的TargetNullValue? –