我有一个使用multibindings生成的运输标签,如下所示:
<TextBox x:Name="TextBoxShippingLabel" Margin="0,10,-2,2" TextWrapping="Wrap">
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}
{2}
{3}
{4}
{5}
{6} {7}">
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[FirstName]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Surname]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Department]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Organisation]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Street]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Suburb]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[State]" />
<Binding ElementName="dataGridOutstandingOrders" Path="SelectedItem[Postcode]" />
</MultiBinding>
</TextBox.Text>
</TextBox>
这很有效,除非组织或部门等数据回复为“无”(在个人订单的情况下会发生)。当发生这种情况时,标签代表如下:
有没有办法可以使用XAML识别绑定何时返回“无”并使用备用StringFormat
?
答案 0 :(得分:3)
我遇到了同样的问题而且我使用了转换器。简单干净:
<MultiBinding Converter="{StaticResource TextAlternateConverter}">
public class TextAlternateConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
StringBuilder myOutputText = new StringBuilder();
foreach (string param in values)
{
if (param == "None")
myOutputText.Append("Give alternate text");
else
myOutputText.Append(param);
}
return myOutputText.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
答案 1 :(得分:1)
我知道你要求没有代码隐藏的解决方案。但是我不认为这是可能的,因为你想要一些&#34; ifs&#34;在你的字符串格式内。这在后面的代码中也是不可能的(参见我提供的扩展方法)。
如果你可以扩展SelectedItem
(无论可能是什么),我会在那里放置一个属性。这可能在将来有用(例如,通过API发送标签)。如果您无法访问代码库,也可以使用ExtensionMethod
。
您至少有2个&#34;变通办法&#34;:
代码背后:
public partial class MainWindow
{
public MainWindow()
{
this.InitializeComponent();
List<OrderViewModel> newList = new List<OrderViewModel>();
newList.Add(new OrderViewModel() { FirstName = "foo", LastName = "bar", Organization = "SO", ZipCode = "666" });
newList.Add(new OrderViewModel() { LastName = "bar", Organization = "SO", ZipCode = "666" });
newList.Add(new OrderViewModel() { FirstName = "foo", ZipCode = "666" });
newList.Add(new OrderViewModel() { FirstName = "foo" });
newList.Add(new OrderViewModel() { FirstName = "foo", LastName = "bar", Organization = "SO", ZipCode = "666" });
DataContext = newList;
}
}
public static class Extensions
{
public static string GenerateShippingLabel(this OrderViewModel order)
{
StringBuilder sb = new StringBuilder();
if (order.FirstName != "None")
{
sb.AppendFormat("{0} ", order.FirstName);
}
if (order.LastName != "None")
{
sb.AppendLine(order.LastName);
}
else
{
sb.AppendLine();
}
if (order.Organization != "None")
{
sb.AppendLine(order.Organization);
}
if (order.ZipCode != "None")
{
sb.AppendLine(order.ZipCode);
}
return sb.ToString();
}
}
public class ShippingLabelConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is OrderViewModel)
{
return (value as OrderViewModel).GenerateShippingLabel();
}
return "None"; //isn't it ironic? ;-)
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class OrderViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Organization { get; set; }
public string ZipCode { get; set; }
public string ShippingLabel
{
get
{
return this.GenerateShippingLabel();
}
}
}
<强> XAML 强>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=ShippingLabel, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding}" Grid.Column="2">
<ItemsControl.Resources>
<local:ShippingLabelConverter x:Key="labelConverter" />
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Converter={StaticResource labelConverter},Mode=OneWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>