绑定到 WPF 中的另一个绑定

ygo*_*goe 0 c# data-binding wpf xaml mvvm

在一个简单的 MVVM 应用程序中,我可以添加对视图中某些属性的绑定。该属性可以访问另一个对象并从中返回属性值。假设我想在视图中显示活动项目。如果没有项目处于活动状态,则应显示特殊注释。

现在,当项目重命名时,名称应该在视图中更新。如果我只是在属性中返回项目名称,它当然不会更新。

所以我想我可以将视图绑定到属性中创建的另一个绑定,该绑定应该转发 PropertyChanged 事件并相应地更新视图。但我看到“System.Windows.Data.Binding”,而不是像“Project: XYZ”这样的绑定的预期结果。

该项目可以在任何地方重命名,因此我想避免从那里自己引发此 ViewModel 的 PropertyChanged 事件。事情本身应该更聪明一点,而不需要从各处推动(当事情变得更加复杂时,你经常会忘记至少一次)。

这是代码:

XAML 视图:

<TextBlock Text="{Binding ActiveProjectName}"/>
Run Code Online (Sandbox Code Playgroud)

C# 视图模型:

public object ActiveProjectName
{
    get
    {
        if (ActiveProject != null)
        {
            // This works but won't update automatically:
            //return "Project: " + ActiveProject.Name;
            // This does not work at all:
            return new Binding("Name")
            {
                Source = ActiveProject,
                StringFormat = "Project: {0}"
            };
        }
        return "(No active project)";
    }
}
Run Code Online (Sandbox Code Playgroud)

这有可能吗?它是如何正确运作的?

pus*_*raj 5

除非ActiveProject属性是私有的或受保护的,否则请在 xaml 中使用FallbackValue 而不是if(ActiveProject != null)在代码隐藏中

例子

<TextBlock Text="{Binding ActiveProject.Name,StringFormat=Project: {0},FallbackValue=(No active project)}"/>
Run Code Online (Sandbox Code Playgroud)

usingPriorityBinding有条件绑定

<TextBlock>
    <TextBlock.Text>
        <PriorityBinding FallbackValue="(No active project)">
            <Binding Path="ActiveProject.Name"
                     StringFormat="Project: {0}"/>
            <Binding Path="SomeOtherProject.Name"
                     StringFormat="Other Project: {0}" />
        </PriorityBinding>
    </TextBlock.Text>
</TextBlock>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,PriorityBinding将首先尝试绑定到ActiveProject,然后使用 Name 属性来解析该值。如果那不可用,即。null,那么它将尝试绑定到SomeOtherProject。要根据绑定解析该值,如果该结果也为 null,则 FallbackValue 将用作 TextBlock 的 Text 属性的值。