2012-06-12 59 views
3

我們的項目需要,我們將控件綁定的許多特性,如HeightWidthMinHeight,,Columnrowspan ...等等。儘管這樣,我們觀察到綁定錯誤,當這些值是我們將從數據庫獲得的null綁定錯誤雖然綁定空值寬度和WPF控件的高度

爲了說明,我的MainWindow.xaml.cs看起來像這樣。

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     //TextWidth id null 
     TextBlockSize1 = new ItemSize() { TextHeight=20 }; 
     //TextWidth is null 
     TextBlockSize2 = new ItemSize() { TextWidth = 40 }; 
     //TextHeight is null and TextWidth is null 
     TextBlockSize3 = new ItemSize() { TextWidth = 40 }; 
     textblock1.DataContext = TextBlockSize1; 
     textblock2.DataContext = TextBlockSize2; 
     textblock3.DataContext = TextBlockSize3; 
    } 
    public ItemSize TextBlockSize1 { get; set; } 

    public ItemSize TextBlockSize2 { get; set; } 

    public ItemSize TextBlockSize3 { get; set; } 
} 

public class ItemSize 
{ 
    public double? TextHeight { get; set; } 
    public double? TextWidth { get; set; } 
} 

MainWindow.xaml看起來是這樣的。顯示

<Window x:Class="WPfAppln1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ctrl="clr-namespace:WPfAppln1.Controls" 
    Title="MainWindow" Height="350" Width="525"> 
    <StackPanel > 
     <TextBlock Name="textblock1" Text=" TextBlock 1" Width="{Binding TextWidth}" Height="{Binding TextHeight}"></TextBlock> 
     <TextBlock Name="textblock2" Text=" TextBlock 2" Width="{Binding TextWidth}" Height="{Binding TextHeight}"></TextBlock> 
     <TextBlock Name="textblock3" Text=" TextBlock 3" Width="{Binding TextWidth, TargetNullValue=Auto}" Height="{Binding TextHeight, TargetNullValue=Auto}"></TextBlock>  
    </StackPanel> 
</Window> 

結合之後的錯誤這個輸出寡婦:

System.Windows.Data Error: 5 : 'WPfAppln1.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Numerics\v4.0_4.0.0.0__b77a5c561934e089\System.Numerics.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextWidth; DataItem='ItemSize' (HashCode=43929715); target element is 'TextBlock' (Name='textblock1'); target property is 'Width' (type 'Double') 
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextHeight; DataItem='ItemSize' (HashCode=57104612); target element is 'TextBlock' (Name='textblock2'); target property is 'Height' (type 'Double') 
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=TextHeight; DataItem='ItemSize' (HashCode=59587750); target element is 'TextBlock' (Name='textblock3'); target property is 'Height' (type 'Double') 
    The thread '<No Name>' (0x2c60) has exited with code 0 (0x0). 

由於這些錯誤的同時,應用程序是需要長時間來加載屏幕。

所以問題是如何容納綁定到wpf控件的可爲空的值以及如何在綁定值爲null時爲控件的寬度屬性提供默認值,如'auto'。

+0

你確定這些綁定錯誤會減慢你的應用程序嗎?我只是好奇心,因爲我一直認爲輸出窗口中的綁定錯誤不會影響性能...... – SvenG

+1

@SvenG:是的,這些綁定錯誤可能會導致性能問題,我個人在DataGrid中遇到過這個問題。 [Here](http://blogs.msdn.com/b/visualstudio/archive/2010/03/02/wpf-in-visual-studio-2010-part-2-performance-tuning.aspx)是一個MS鏈接說 - 「WPF嘗試幾種不同的方式來解決路徑錯誤,包括搜索附加的屬性,這是非常昂貴的」**,也見[this](http://social.msdn.microsoft.com/Forums/is/wpf/thread/eb6b83b5-bcbb-4e1f-af03-cde68cfe827d) – akjoshi

+0

感謝您的洞察力,這對我來說非常有用! – SvenG

回答

3

您可以使用TargetNullValue(如果源爲null)或FallbackValue(如果綁定失敗,例如DataContextnull

更新:

感謝院長指出了這一點,我錯誤地認爲Auto將工作(即TypeConverter將負責轉換)。

但是,你仍然可以使用自動屬性和使用x:Static Markup Extension像這樣的XAML提供Auto價值 -

<TextBlock Name="textblock1" Text=" TextBlock 1" 
    Height="{Binding TextHeight, TargetNullValue={x:Static System:Double.NaN}, 
       FallbackValue={x:Static System:Double.NaN}}"> 
</TextBlock> 

Value="{x:Static System:Double.NaN}"也可以在DataTrigger方法一起使用這樣的 -

<TextBlock.Style> 
    <Style> 
     <Setter Property="Control.Width" Value="{Binding Path=TextWidth}" /> 
     <Style.Triggers> 
      <DataTrigger 
       Binding="{Binding Path=TextWidth}" 
       Value="{x:Null}"> 
       <Setter Property="Control.Width" Value="{x:Static System:Double.NaN}" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</TextBlock.Style> 

注意:將需要這個命名空間 -

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

舊代碼:

<TextBlock Name="textblock1" Text=" TextBlock 1" Width="{Binding TextWidth}" 
    Height="{Binding TextHeight, TargetNullValue=Auto, FallbackValue=Auto }"> 
</TextBlock> 

另一種解決方案可能是有一個觸發這樣的 -

<TextBlock.Style> 
    <Style> 
     <Style.Triggers> 
      <DataTrigger 
       Binding="{Binding Path=TextWidth}" 
       Value="{x:Null}"> 
       <Setter Property="Control.Width" Value="Auto" /> 
      </DataTrigger> 
      <DataTrigger 
       Binding="{Binding Path=TextHeight}" 
       Value="{x:Null}"> 
       <Setter Property="Control.Height" Value="Auto" /> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</TextBlock.Style> 
+0

-1:不能將字符串'Auto'用作TargetNullValue或FallbackValue,因此您的解決方案無法工作 –

+1

+1感謝TargetNullValue。我只是想在bool目標中重用一個可爲空的布爾,所以這工作'IsEnabled =「{綁定路徑= ItemEnabled,轉換器= {StaticResource negate},TargetNullValue = false}」# – reasra

+0

@reasra很高興它幫助:) – akjoshi

1

最簡單的解決方案(在我看來)是不使用自動屬性。

例如

private double textHeight = Double.NaN; 
public double TextHeight 
{ 
    get { return textHeight; } 
    set { textHeight = value; } 
} 

private double textWidth = Double.NaN; 
public double TextWidth 
{ 
    get { return textWidth; } 
    set { textWidth = value; } 
} 
0

如果你的兩個double?性質不是絕對需要的是空的,你可以讓他們定期double性能。這將默認爲0。

如果這是不可能的,或0是一個不可接受的默認值,我會自己傾向於FallbackValue解決方案。如果您的默認值必須是「自動」(如上所述),則不能將「自動」設置爲FallbackValue

高度和寬度的默認值不是0;它是Double.NaN。 高度和寬度支持未設置「自動」值的能力。 由於高度和寬度是雙倍值,因此使用Double.NaN作爲特殊值來表示此「自動」行爲。 (從http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width(v=VS.95).aspx

如果您不能設置Double.NaNFallbackValue(我沒試過),我會用自己的轉換器。如果目標值爲null,則返回Double.NaN。有關IVAlueConverter的更多信息,請訪問http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

相關問題