简体   繁体   English

如何使用WPF和MVVM模式将控件绑定到列表框中的选定项目?

[英]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. 现在,我将Department选项卡的DataContext属性绑定到Department对象的ObservableCollection,然后仅在右侧的文本框中引用Department对象的属性。 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. 我想做的是有一个指向特定部门对象的指针,该对象是在ViewModel内部用ListBox选择的。 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. 这样,我应该能够在右侧的文本框中进行单向绑定,并在单击“保存更改”按钮后将更改保存到SQL Compact DB。

Sample ViewModel: 样本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. 您的dataContext应该是整个ViewModel,而不是集合。 Then you can set in listBox 然后可以在listBox中设置

ItemsSource="{Binding Departments}"

and in the Grid 并在网格中

DataContext="{Binding Departments}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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