Xaml - 在 FallBackValue 中绑定

Xaml - Binding in FallBackValue

我如何在网格中的列上进行两个绑定,如果第一个绑定为空或 null,将使用第二个绑定。我曾尝试使用 FallbackValue 属性 来做到这一点,但您不能仅在其中绑定静态值。 这里有一些代码,这不仅仅是文字!

<telerik:RadGridView x:Name="radGridView">
     <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumn DataMemberBinding="{Binding FirstName,
            FallbackValue=Binding FirstName2}"  //You cant do that!
            Header="First Name" />
     </telerik:RadGridView.Columns>
</telerik:RadGridView>

xaml一定有办法做到!请帮忙!

你可以为此使用 DataTriggers,像这样

<telerik:RadGridView x:Name="radGridView">
  <telerik:RadGridView.Columns>
    <telerik:GridViewDataColumn Header="First Name">
        <telerik:GridViewDataColumn.Style>
            <Style TargetType="{x:Type telerik:GridViewDataColumn}">
              <Setter Property="DataMemberBinding" Value="{Binding FirstName}"/>
              <Style.Triggers>
                  <DataTrigger Binding="{Binding FirstName}" Value="{x:Null}">
                      <Setter Property="DataMemberBinding" Value="{Binding FirstName2}"/>
                  </DataTrigger>
              </Style.Triggers>
            </Style>
        </telerik:GridViewDataColumn.Style>
    </telerik:GridViewDataColumn>
  </telerik:RadGridView.Columns>
</telerik:RadGridView>

我至少能想到两个办法:

第一个解决方案(在 DataContext 中解决): 将 属性 添加到您的 DataContext 类型,例如 ResolvedFirstName 并且该值取自 FirstNameFirstName2,并且当两者中的任何一个发生更改时 ResolvedFirstName 重新评估。

public string ResolvedFirstName {
    get { return string.IsNullOrEmpty(FirstName) ? FirstName2 : FirstName; }
}

public string FirstName {
    get {...}
    set {...
        RaisePropertyChanged("FirstName");
        RaisePropertyChanged("ResolvedFirstName");}
}

public string FirstName2 {
    get {...}
    set {...
        RaisePropertyChanged("FirstName2");
        RaisePropertyChanged("ResolvedFirstName");}
}

第二个解决方案(在视图中解决): 添加一个 StringMultiplexer 作为 StaticResource 绑定到两个属性,它提供了一个 Output 属性 你的专栏可以绑定。

<RadGridView>
    <RadGridView.Resources>
        <StringMultiplexer x:Key="FirstNameMux"
            HighPrioString="{Binding FirstName}"
            LowPrioString="{Binding FirstName2}"/>
    </RadGridView.Resources>
    <RadGridView.Columns>
        <GridViewDataColumn
            DataMemberBinding="{Binding Output, Source={StaticResource FirstNameMux}}"/>

和代码:

public class StringMultiplexer : DependencyObject
{
    public string LowPrioString
    {
        get { return (string) GetValue( LowPrioStringProperty ); }
        set { SetValue( LowPrioStringProperty, value ); }
    }

    public static readonly DependencyProperty LowPrioStringProperty =
        DependencyProperty.Register( "LowPrioString", typeof( string ), typeof( StringMultiplexer ), new PropertyMetadata( DetermineOutput ) );

    public string HighPrioString
    {
        get { return (string) GetValue( HighPrioStringProperty ); }
        set { SetValue( HighPrioStringProperty, value ); }
    }

    public static readonly DependencyProperty HighPrioStringProperty =
        DependencyProperty.Register( "HighPrioString", typeof( string ), typeof( StringMultiplexer ), new PropertyMetadata( DetermineOutput ) );

    public string Output
    {
        get { return (string) GetValue( OutputProperty ); }
        set { SetValue( OutputProperty, value ); }
    }

    public static readonly DependencyProperty OutputProperty =
        DependencyProperty.Register( "Output", typeof( string ), typeof( StringMultiplexer ), null );

    private static void DetermineOutput( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ((StringMultiplexer) d).DetermineOutput();
    }

    private void DetermineOutput()
    {
        Output = (string.IsNullOrEmpty( HighPrioString )) ? LowPrioString : HighPrioString;
    }
}

当我输入第二个解决方案时,我开始怀疑这个解决方案是否适用于您的具体情况。我自己使用了 StringMultiplexer 并且它按预期工作。我在你的案例中看到的问题是:GridViewDataColumn 不是 FrameworkElement(据我所知),而只是一个 Column-definition-object,它为实际单元格控件或行控件实例化时提供蓝图,而 DataMemberBinding 将最可能针对为其创建行的项目对象进行解析。也许您需要从 GridViewDataColumn 派生并在那里实现多路复用器。