【问题标题】:WPF / MVVM - Title BindingWPF / MVVM - 标题绑定
【发布时间】:2018-03-16 16:02:54
【问题描述】:

我在 WPF 中使用 MVVM 模式。我的小项目包含 1x Window 和 3x UserControls。每个UserControl代表tab,如下图所示。

Solution structure

我要做的是将窗口标题绑定到每个选项卡模型中的变量。我尝试使用 Interaction.Triggers 和事件名称“Loaded”。当我在不同视图之间切换时,命令“ChangeTitle”工作正常,但是当我选择与先前选择的选项卡具有相同视图的选项卡时,标题不会改变,直到我切换到具有不同视图的另一个选项卡。我尝试了其他事件,但找不到任何用于此目的的事件。我想在选项卡选择更改后触发上述命令。请指教。谢谢。

MainWindow.xaml

<Window x:Class="LSS_doc.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:models="clr-namespace:LSS_doc.Models"
    xmlns:Views="clr-namespace:LSS_doc.Views"
    mc:Ignorable="d"
    Height="350" Width="525"
    MinHeight="350"
    MinWidth="525">

<Grid>
    <intr:Interaction.Triggers>
        <intr:EventTrigger EventName="Loaded">
            <intr:InvokeCommandAction Command="{Binding CreateMainTab}"/>
        </intr:EventTrigger>
    </intr:Interaction.Triggers>
    <DockPanel>
        <TabControl Name="tabControl" ItemsSource="{Binding Tabs}" SelectedIndex="{Binding TabIndex}">
            <TabControl.Resources>
                <DataTemplate DataType="{x:Type models:MainTabModel}">
                    <Views:MainTabView/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:ResultTabModel}">
                    <Views:ResultTabView/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type models:DisplayTabView}">
                    <Views:DisplayTabView/>
                </DataTemplate>
            </TabControl.Resources>

            <TabControl.ItemTemplate>
                <DataTemplate DataType="{x:Type models:ITabModel}">
                    <TextBlock>
                    <Run Text="{Binding Name}"/>
                    <Hyperlink Command="{Binding CloseCommand}" ><Run Text="{Binding CloseButton}"/></Hyperlink>
                    </TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>
    </DockPanel>
</Grid>

MainTabView.xaml

<UserControl x:Class="LSS_doc.Views.MainTabView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         mc:Ignorable="d"

         d:DesignHeight="450" d:DesignWidth="800">
<intr:Interaction.Triggers>
    <intr:EventTrigger EventName="Loaded">
        <intr:InvokeCommandAction CommandParameter="{Binding Name}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ChangeTitle}"/>
    </intr:EventTrigger>
</intr:Interaction.Triggers>
<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="100"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBox Name="searchBox" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Keywords}" Margin="10,10,10,10" Height="30"/>
    <Button Name="searchButton" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Search}" Grid.Column="1" Margin="0,0,10,0" Height="30"/>
    <TreeView Grid.Row="1" Grid.ColumnSpan="2" Margin="10,0,10,10" BorderThickness="0">
        <TreeViewItem Header="{Binding Name}" IsExpanded="True">
            <TreeViewItem Header="Level 2.1" />
            <TreeViewItem Header="Level 2.2" IsExpanded="True">
                <TreeViewItem Header="Level 3.1" />
                <TreeViewItem Header="Level 3.2" />
            </TreeViewItem>
            <TreeViewItem Header="Level 2.3" />
        </TreeViewItem>
    </TreeView>
</Grid>

ResultTabView.xaml

<UserControl x:Class="LSS_doc.Views.ResultTabView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<intr:Interaction.Triggers>
    <intr:EventTrigger EventName="Loaded">
        <intr:InvokeCommandAction CommandParameter="{Binding Name}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ChangeTitle}"/>
    </intr:EventTrigger>
</intr:Interaction.Triggers>
<Grid>
    <ListBox x:Name="FileList" ItemsSource="{Binding Result}">
        <ListBox.ItemTemplate>
            <DataTemplate DataType="string">
                <TextBlock>
                    <Hyperlink CommandParameter="{Binding}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.DisplayFile}">
                        <TextBlock Text="{Binding}"/>
                    </Hyperlink>
                </TextBlock>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

DisplayTabView.xaml

<UserControl x:Class="LSS_doc.Views.DisplayTabView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:LSS_doc.Helpers"
         xmlns:ns="clr-namespace:LSS_doc.Helpers"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<intr:Interaction.Triggers>
    <intr:EventTrigger EventName="Loaded">
        <intr:InvokeCommandAction CommandParameter="{Binding Name}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ChangeTitle}"/>
    </intr:EventTrigger>
</intr:Interaction.Triggers>
<Grid >
    <WebBrowser local:WebBrowserExtensions.BindableSource="{Binding FileUrl}" local:WebBrowserExtensions.BindableLoaded="{Binding AcceptedKeywords}"/>
</Grid>

【问题讨论】:

  • 如何将 Title 属性绑定到所选项目的属性,例如 Title="{Binding SelectedItem.TitleProperty, ElementName=tabControl}" ?提问时请提供您问题的 MCVE:stackoverflow.com/help/mcve
  • 非常感谢!就是这么简单……

标签: c# wpf mvvm binding


【解决方案1】:

您可以使用 ElementName 将 Window Title 直接绑定到模型:

<Window Title="{Binding ElementName=tab,Path=SelectedItem.WindowTitleForThisTab}">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2021-03-01
    相关资源
    最近更新 更多