我们的项目需要绑定控件的许多属性,例如Height
,Width
,MinHeight
,Row
,Column
,{{1}在这样做的同时,我们观察到绑定错误,当这些值为rowspan
时,我们将从DB获取。
为了说明,我的 MainWindow.xaml.cs 看起来像这样。
null
和 MainWindow.xaml 看起来像这样。
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; }
}
在输出窗口中显示以下绑定错误:
<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>
由于这些错误,应用程序需要很长时间才能加载屏幕。
所以问题是如何在绑定到wpf控件时容纳可空值以及如何在绑定值为null时为控件的宽度属性提供默认值,例如'auto'。
答案 0 :(得分:3)
您可以使用TargetNullValue
(如果来源为空)或FallbackValue
(如果绑定失败,例如DataContext
为null
)
<强>更新强>
感谢Dean指出这一点,我错误地认为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>
答案 1 :(得分:2)
最简单的解决方案(在我看来)不使用自动属性。
e.g。
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; }
}
答案 2 :(得分:0)
如果您的两个double?
属性并非绝对需要可以为空,那么您可以将它们设为常规double
属性。这将默认为0.
如果那是不可能的,或者0是不可接受的默认值,我会赞成自己的FallbackValue解决方案。如果您的默认值必须为“自动”(如上所述),则无法将“自动”设置为FallbackValue
。
高度和宽度的默认值不为0;它是Double.NaN。 高度和宽度支持未设置“自动”值的能力。 因为Height和Width是double值,所以Double.NaN用作a 表示此“自动”行为的特殊值。 (来自http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width(v=VS.95).aspx)
如果您无法将Double.NaN
设置为FallbackValue
(我还没试过),我会自己使用转换器。如果目标值为null
,请返回Double.NaN
。有关IVAlueConverter的更多信息,请http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx。