【问题标题】:Bind selected item to a StackPanel将所选项目绑定到 StackPanel
【发布时间】:2018-01-16 14:04:05
【问题描述】:

我正在尝试制作一个 WPF 程序,其中有一个 AgreementModel。然后使用ListView 控件显示协议,但仅显示几个关键属性。然后我有一个StackPanel 控件,用于显示所选项目的所有协议详细信息。我为每种显示项目的方式制作了DataTemplate

这就是我的问题所在。虽然我可以轻松地将 ListView 绑定到协议(视图模型中的 ObservableCollection),但我根本无法弄清楚如何将详细信息绑定到所选协议(视图模型中的 AgreementModel)。

我能找到的一切似乎都与绑定集合有关。如何仅将所选项目绑定到 StackPanel 或类似名称?

查看 XAML

<UserControl.Resources>
    <!--Template for list view-->
    <DataTemplate x:Key="agreementRowTemplate">
        <StackPanel Orientation="Horizontal">

            <TextBlock
                Text="{Binding Path=Property1}" />

            <TextBlock
                Text="{Binding Path=Property2}" />

            <TextBlock
                Text="{Binding Path=Property3}" />

        </StackPanel>
    </DataTemplate>

    <!--Template for the detail view-->
    <DataTemplate x:Key="agreementDetailTemplate">
        <StackPanel>
            <TextBlock
            Text="Property 1:" />

            <TextBox
            Text="{Binding Path=Property1}" />

        </StackPanel>            
    </DataTemplate>
</UserControl.Resources>

<Grid Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="600" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>

    <!-- This list view works as intended -->
    <ListBox
        Grid.Column="1"
        ItemsSource="{Binding Agreements}"
        SelectedItem="{Binding SelectedAgreement}"
        ItemTemplate="{StaticResource agreementRowTemplate}"/>

    <!-- I am trying to add my detail view here -->
    <ItemsControl ItemTemplate="{StaticResource agreementDetailTemplate}" ItemsSource="{Binding SelectedAgreement}">
    </ItemsControl>

</Grid>

ViewModel C#

private AgreementModel selectedAgreement;

public ValuationViewModel()
{
    LoadAgreements();
}

public ObservableCollection<AgreementModel> Agreements
{
    get; set; 
}

// I have tried 'return Agreements[0]' to check if this was the problem
public AgreementModel SelectedAgreement
{
    get { return _selectedAgreement; }
    set { selectedAgreement = value; }
}

public void LoadAgreements()
{
    ObservableCollection<AgreementModel> agreements =
        new ObservableCollection<AgreementModel>();

    agreements.Add(new AgreementModel { Property1 = 123, Property2 = "Some Text", Property3 = "Status: OK" });
    agreements.Add(new AgreementModel { Property1 = 456, Property2 = "Some Text", Property3 = "Status: Not OK" });
    agreements.Add(new AgreementModel { Property1 = 789, Property2 = "Some Text", Property3 = "Status: Somewhat OK" });

    Agreements = agreements;
}

【问题讨论】:

  • 对于单个项目 (SelectedAgreement),您也可以使用 ContentControl 而不是 ItemsControl。无论如何,当ListView 选定的项目发生变化时,只需适当地设置SelectedAgreement ......怎么样?见stackoverflow.com/a/29885442/1207195

标签: c# wpf xaml listview data-binding


【解决方案1】:

ItemsControl 用于显示项目的集合,或者更确切地说是 IEnumerable

如果您只想在StackPanel 中显示当前选定AgreementModel 的详细信息,可以将其DataContext 绑定到SelectedAgreement 属性或使用ContentControl

<ContentControl Content="{Binding SelectedAgreement}" ContentTemplate="{StaticResource agreementDetailTemplate}" />

<StackPanel DataContext="{Binding SelectedAgreement}">
...
</StackPanel>

您还应该确保您的视图模型类实现了INotifyPropertyChanged 接口,并在设置SelectedAgreement 属性时引发PropertyChanged 事件。

否则ContentControl/StackPanel 将不会在您选择ListBox 中的项目时更新。

【讨论】:

  • 感谢您的意见。这说得通。我明天上班时试试看:-)
  • 完美运行,谢谢。我已经在一个基础中实现了INotifyPropertyChanged,然后我在视图模型中继承了它。所以现在一切正常:-)
【解决方案2】:

您需要将 SelectedIndex 绑定到 ViewModel 中的属性(例如 SelectedAgreementIndex)。然后,在SelectedAgreementIndex 属性的设置器中,您可以基于SelectedIndex 设置SelectedAgreement 属性。然后它只是使用例如绑定到SelectedAgreement使用您的数据模板的视图中的ContentControl

【讨论】:

    猜你喜欢
    • 2013-05-22
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2011-03-22
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多