简体   繁体   中英

How to show properties of listbox selected item in different controls

In my application I have a window which contain a ListBox , and controls that should show different properties of its currently selected item. Those controls are:

  1. TextBox that should show 'Name' property.
  2. TextBox that should show 'DataFile` property.
  3. DataGrid that should show 'TItems property, which is an ObservableCollection .

I tried to bind SelectedItem to an object, and then bind different properties of that object to the controls mentioned above, with no success.

The window:

在此处输入图片说明

My View:

<Window
    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:local="clr-namespace:ReportMaker"
    xmlns:ViewModel="clr-namespace:ReportMaker.ViewModel" x:Class="ReportMaker.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <ViewModel:MainViewModel/>
</Window.DataContext>
<Grid>
    <Button x:Name="button" Content="Create" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="75"/>
    <ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="10,0,0,10" VerticalAlignment="Bottom" Width="120"/>
    <ListBox x:Name="listBox" HorizontalAlignment="Left" Margin="10,10,0,36.667" Width="119" ItemsSource="{Binding ReportItems}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <StackPanel HorizontalAlignment="Left" Height="274" Margin="134,10,0,0" VerticalAlignment="Top" Width="375" DataContext="{Binding SelectedReportItem}">
        <StackPanel.Resources>
            <Style x:Key="ControlBaseStyle" TargetType="{x:Type Control}">
                <Setter Property="Margin" Value="0, 10, 0, 0" />
            </Style>
        </StackPanel.Resources>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Name:"/>
            <TextBox Width="150" Text="{Binding Name}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Data File:"/>
            <TextBox Width="150" Text="{Binding ID}"/>
        </StackPanel>
        <DataGrid Height="190" VerticalAlignment="Bottom" ItemsSource="{Binding TItems}"/>
    </StackPanel>
    <Button x:Name="button_Copy" Content="Save" HorizontalAlignment="Right" Margin="0,0,92,10" VerticalAlignment="Bottom" Width="75"/>

</Grid>
</Window>

My ViewModel:

public class MainViewModel
{
    public ObservableCollection<ReportItem> ReportItems { get; set; }
    public object SelectedReportItem { get; set; }
    public MainViewModel()
    {
        ReportItems = new ObservableCollection<ReportItem>();
        ReportItems.Add(Example);
    }
    public ReportItem Example = new TextReportItem() { Name = "John", DataFile = "try.txt"};
}

ReportItem:

public class ReportItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string DataFile { get; set; }
}

TextReportItem:

public class TextReportItem : ReportItem
{
    public ObservableCollection<TextParcel> TItems { get; set; }
}
public class TextParcel
{
    char Delimiter { get; set; }
    string LineExp { get; set; }
    string Result { get; set; }
    string IgnoreLine { get; set; }
    int DesiredResultIndexInLine { get; set; }
}

EDIT: as I use MVVM, I prefer to use only XAML in the View, with no code behind.

EDIT 2:

Thanks to S.Akbari I succeeded to view the desired properties in the TextBox controls, with the following code:

<StackPanel Orientation="Horizontal">
            <TextBlock Text="Name:"/>
            <TextBox Width="150" Text="{Binding ElementName=listBox, Path=SelectedItem.Name}"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Data File:"/>
            <TextBox Width="150" Text="{Binding ElementName=listBox, Path=SelectedItem.DataFile}"/>
        </StackPanel>

But when the same logic is applied to my DataGrid , it fails for some reason:

<DataGrid Height="190" VerticalAlignment="Bottom" ItemsSource="{Binding ElementName=listBox, Path=SelectedItem.TItmes}" />

I also tried:

<DataGrid Height="190" VerticalAlignment="Bottom" DataContext="{Binding ElementName=listBox, Path=SelectedItem}" ItemsSource="{Binding TItems}"/>

And also:

<DataGrid Height="190" VerticalAlignment="Bottom" DataContext="{Binding ElementName=listBox, Path=SelectedItem}">
            <DataTemplate>
                <TextBlock Text="{Binding TItems}" />
            </DataTemplate>
        </DataGrid>

if you use MVVM your view model should raise property changed events
You should implement INotifyPropertyChanged and change the selected item to be a full property see : How to: Implement Property Change Notification

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM