C# 拆下';无';不使用代码隐藏从文本框

C# 拆下';无';不使用代码隐藏从文本框,c#,wpf,xaml,C#,Wpf,Xaml,我有一个使用多重绑定生成的装运标签,如下所示: <TextBox x:Name="TextBoxShippingLabel" Margin="0,10,-2,2" TextWrapping="Wrap"> <TextBox.Text> <MultiBinding StringFormat="{}{0} {1}&#x0a;{2}&#x0a;{3}&#x0a;{4}&#x0a;{5}&#x0a;{6} {7

我有一个使用多重绑定生成的装运标签,如下所示:

<TextBox x:Name="TextBoxShippingLabel" Margin="0,10,-2,2" TextWrapping="Wrap">
    <TextBox.Text>
        <MultiBinding StringFormat="{}{0} {1}&#x0a;{2}&#x0a;{3}&#x0a;{4}&#x0a;{5}&#x0a;{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>

这非常有效,除非组织或部门等数据返回为“无”(这发生在个人订单的情况下)。发生这种情况时,标签表示如下:

<TextBox x:Name="TextBoxShippingLabel" Margin="0,10,-2,2" TextWrapping="Wrap">
    <TextBox.Text>
        <MultiBinding StringFormat="{}{0} {1}&#x0a;{2}&#x0a;{3}&#x0a;{4}&#x0a;{5}&#x0a;{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来识别绑定何时返回“None”并使用备用的
StringFormat

我也有同样的问题,我使用了一个转换器。简单清洁:

  <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();
    }
}

公共类TextAlternateConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,System.Globalization.CultureInfo区域性)
{
StringBuilder myOutputText=新建StringBuilder();
foreach(值中的字符串参数)
{
如果(参数=“无”)
myOutputText.Append(“提供替代文本”);
其他的
myOutputText.Append(参数);
}
返回myOutputText.ToString();
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,System.Globalization.CultureInfo区域性)
{
抛出新系统。NotImplementedException();
}
}

我知道您要求的解决方案没有代码隐藏。但是我认为这是不可能的,因为您希望在字符串格式中包含一些“如果”。这在代码隐藏中也是不可能的(另请参阅我提供的扩展方法)

如果您可以扩展
SelectedItem
(不管是什么),我会在那里放置一个属性。这在将来可能会有所帮助(例如,通过API发送标签)。如果无法访问代码库,也可以使用
ExtensionMethod

您至少有2个“变通办法”:

代码隐藏:

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();
        }
    }
}
公共部分类主窗口
{
公共主窗口()
{
this.InitializeComponent();
List newList=新列表();
添加(neworderviewmodel(){FirstName=“foo”,LastName=“bar”,Organization=“SO”,ZipCode=“666”});
添加(neworderViewModel(){LastName=“bar”,Organization=“SO”,ZipCode=“666”});
添加(neworderviewmodel(){FirstName=“foo”,ZipCode=“666”});
Add(neworderviewmodel(){FirstName=“foo”});
添加(neworderviewmodel(){FirstName=“foo”,LastName=“bar”,Organization=“SO”,ZipCode=“666”});
DataContext=newList;
}
}
公共静态类扩展
{
公共静态字符串GenerateShippingLabel(此OrderViewModel订单)
{
StringBuilder sb=新的StringBuilder();
如果(order.FirstName!=“无”)
{
sb.AppendFormat(“{0}”,order.FirstName);
}
如果(order.LastName!=“无”)
{
某人追加(订单、姓氏);
}
其他的
{
(某人);
}
如果(order.Organization!=“无”)
{
某人(命令、组织);
}
如果(order.ZipCode!=“无”)
{
sb.追加行(顺序ZipCode);
}
使某人返回字符串();
}
}
公共类ShippingLabelConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
如果(值为OrderViewModel)
{
返回(值为OrderViewModel);
}
返回“无”;//这不是很讽刺吗?;-)
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
公共类OrderViewModel
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串组织{get;set;}
公共字符串ZipCode{get;set;}
公共字符串发货标签
{
得到
{
返回此值。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>


您愿意使用多值转换器而不是StringFormat吗?TargetNullValue会帮助您吗???@BradleyDotNET完全开放,但以前从未接触过。它在这样的用例中合适吗?@mohithrivastava不幸地不合适。项目源没有返回Null,但返回“None”-它不是我的代码库(我只添加了一个特性),因此我不相信我可以在不引入风险的情况下更改它。这是公平的,如果可能的话,我只是尝试坚持使用XAML!很高兴知道我并没有太离谱。