4

Height私たちのプロジェクトでは、WidthMinHeightRowColumn、 ... などのコントロールの多くのプロパティをバインドする必要があります。そうしている間に、これらの値がDB から取得されるrowspanときにバインド エラーが発生することがわかりました。null

説明のために、私の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 許容値に対応する方法と、バインドされた値が null の場合にコントロールの幅プロパティに「auto」などのデフォルト値を提供する方法です。

4

3 に答える 3

3

TargetNullValue(ソースがnullの場合)またはFallbackValue(バインディングが失敗した場合、たとえばDataContextis null)を使用できます

アップデート:

それを指摘してくれたディーンに感謝します。私はそれAutoがうまくいくと誤って想定していました(つまりTypeConverter、変換を処理します)。

ただし、このようにマークアップ拡張機能Autoを使用して、auto プロパティを使用し、XAML で値を提供することができます-x:Static

<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>
于 2012-06-12T12:09:44.637 に答える
2

(私の意見では)最も簡単な解決策は、自動プロパティを使用しないことです。

例えば

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; }
}
于 2012-06-12T12:30:34.613 に答える
0

2 つのdouble?プロパティが絶対に null 可能である必要がない場合は、それらを通常doubleのプロパティにすることができます。これはデフォルトで 0 になります。

それが不可能な場合、または 0 が許容できないデフォルトである場合は、FallbackValue ソリューションを自分で使用することをお勧めします。ただし、(前述のように) デフォルト値を「Auto」にする必要がある場合、「Auto」を として設定することはできませんFallbackValue

高さと幅のデフォルト値は 0 ではありません。Double.NaN です。高さと幅は、設定されていない「自動」値になる機能をサポートしています。Height と Width は double 値であるため、Double.NaN は、この「自動」動作を表す特別な値として使用されます。( http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width(v=VS.95).aspxから)

Double.NaNに設定できない場合FallbackValue(私は試していません)、自分でコンバーターを使用します。ターゲット値が の場合は、代わりnullに returnを返しDouble.NaNます。IVAlueConverterの詳細については、http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx を参照してください。

于 2012-06-12T12:52:45.477 に答える