简体   繁体   中英

How do I bind controls to the selected item in a listbox using WPF and the MVVM pattern?

I currently have a working method, but does not work for what I need. Here's how the Settings window looks:

Right now I am binding the Department tab DataContext property to an ObservableCollection of Department objects, and then I just refer to the properties of the Department object in the text boxes to the right. Here is the code for this tab:

<TabItem Header="Department Settings"
             DataContext="{Binding Departments}">
        <DockPanel Margin="3,3,3,3">
            <DockPanel DockPanel.Dock="Left"
                       Width="200">
                <StackPanel DockPanel.Dock="Bottom"
                            Margin="0,5,0,0"
                            Orientation="Horizontal">
                    <TextBox x:Name="tbxAddDepartmentName"
                             Width="160"
                             Padding="0,5,0,5" />
                    <Button x:Name="btnAddDepartment"
                            Content="Add"
                            Margin="5,0,5,0"
                            Padding="5,5,5,5"
                            Command="{Binding AddDepartmentCommand, UpdateSourceTrigger=PropertyChanged}" />
                </StackPanel>
                <ListBox ItemsSource="{Binding}" />
            </DockPanel>

            <StackPanel DockPanel.Dock="Bottom">
                <Button Content="Save Changes"
                        Padding="5,5,5,5"
                        HorizontalAlignment="Right" />
            </StackPanel>
            <Grid Margin="5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="150" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <!-- Labels -->
                <Label Grid.Row="0" Grid.Column="0">Department Name:</Label>
                <Label Grid.Row="1" Grid.Column="0">Report Number:</Label>
                <Label Grid.Row="2" Grid.Column="0">Address:</Label>

                <!-- Input -->
                <TextBox x:Name="tbxDepartmentName"
                         Text="{Binding Name}"
                         Grid.Row="0" Grid.Column="1"
                         VerticalContentAlignment="Center"
                         Margin="0,5,0,5"
                         Padding="5" />
                <TextBox Grid.Row="1" Grid.Column="1"
                         Text="{Binding ReportNumber}"
                         VerticalContentAlignment="Center"
                         Margin="0,5,0,5"
                         Padding="5" />
                <TextBox Grid.Row="2" Grid.Column="1"
                         Text="{Binding Address}"
                         VerticalContentAlignment="Center"
                         AcceptsReturn="True"
                         Margin="0,5,0,5"
                         Padding="5" />
            </Grid>
        </DockPanel>
    </TabItem>

What I want to do is have a pointer to the specific Department object that is selected with the ListBox inside my ViewModel. This way, I should be able to do a one way binding on the textboxes to the right, and save change to the SQL Compact DB after I hit the "Save Changes" Button.

Sample ViewModel:

public class ViewModel : INotifyPropertyChanged, INotifyPropertyChanging
{
    public class MyObj
    {
        public string Test1 { get; set; }
        public string Test2 { get; set; }
    }

    #region selectedItem

    private MyObj _selectedItem;

    public MyObj selectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            if (_selectedItem != value)
            {
                NotifyPropertyChanging("selectedItem");
                _selectedItem = value;
                NotifyPropertyChanged("selectedItem");
            }
        }
    }
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    #region INotifyPropertyChanging Members

    public event PropertyChangingEventHandler PropertyChanging;

    // Used to notify the data context that a data context property is about to change
    protected void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    #endregion
}

Add to your ListBox:

SelectedItem="{Binding selectedItem, UpdateSourceTrigger=PropertyChanged}"

Your dataContext should be whole ViewModel, not a collection. Then you can set in listBox

ItemsSource="{Binding Departments}"

and in the Grid

DataContext="{Binding Departments}"

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