简体   繁体   English

设置SelectedIndex时取消ListBox.SelectedItem绑定

[英]ListBox.SelectedItem binding canceled when setting SelectedIndex

I have some problems with databinding... here is the situation: 我在数据绑定方面遇到了一些问题...情况如下:

my View: 我的观点:

<Window x:Class="Shifter.Forms.Employee.frmEditEmployee"
        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"
        mc:Ignorable="d"
        Title="frmEditEmployee" Height="350.141" Width="497.195" WindowStyle="None" ResizeMode="NoResize" Foreground="Blue" WindowStartupLocation="CenterScreen">        

    <Grid>    
        <ListBox x:Name="lstEmployee" IsEnabled="{Binding NoEditMode}" SelectedItem="{Binding MasterEmployee}" ItemsSource="{Binding Path=ListOfEmployees}" HorizontalAlignment="Left" Height="276" Margin="25,19,0,0" VerticalAlignment="Top" Width="217" />
        <TextBox x:Name="txtForename" Text="{Binding SelectedItem.Forname, ElementName=lstEmployee}" Margin="342,21,0,0" GotFocus="SelectText"/>
        <TextBox x:Name="txtLastname" Text="{Binding SelectedItem.Lastname, ElementName=lstEmployee}" Margin="342,47,0,0" GotFocus="SelectText"/>
        <TextBox x:Name="txtShowingname" Text="{Binding SelectedItem.Showingname, ElementName=lstEmployee}" Margin="342,74,0,0" GotFocus="SelectText"/>
        <TextBox x:Name="txtPersonelNumber" Text="{Binding SelectedItem.EmployeeID, ElementName=lstEmployee}" Margin="342,99,0,0" GotFocus="SelectText"/>
        <DatePicker x:Name="dtpBirthday" SelectedDate="{Binding SelectedItem.Birthday, ElementName=lstEmployee}" HorizontalAlignment="Left" Margin="342,125,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.256,0.417" SelectedDateFormat="Short"/>
        <TextBox x:Name="txtLoan" Text="{Binding SelectedItem.Loan, ElementName=lstEmployee}" Margin="342,151,0,0" TextWrapping="Wrap" GotFocus="SelectText"/>
        <TextBox x:Name="txtPhone" Text="{Binding SelectedItem.Telephone, ElementName=lstEmployee}" Margin="342,229,0,0" TextWrapping="Wrap" GotFocus="SelectText"/>
        <TextBox x:Name="txtEMail" Text="{Binding SelectedItem.EMail, ElementName=lstEmployee}" Margin="342,255,0,0" TextWrapping="Wrap" GotFocus="SelectText"/>
        <ComboBox x:Name="cmbContract" ItemsSource="{Binding ListOfContracts, Mode=TwoWay}" SelectedItem="{Binding SelectedItem.Contract, ElementName=lstEmployee, Mode=TwoWay}" HorizontalAlignment="Left" Margin="342,179,0,0" VerticalAlignment="Top" Width="130"/>
        <ComboBox x:Name="cmbGroup" ItemsSource="{Binding ListOfGroups, Mode=TwoWay}" SelectedItem="{Binding SelectedItem.Group, ElementName=lstEmployee, Mode=TwoWay}" HorizontalAlignment="Left" Margin="342,204,0,0" VerticalAlignment="Top" Width="130"/>
        <CheckBox x:Name="chkHide" Content="MA im Dienstplan ausblenden" IsChecked="{Binding SelectedItem.isHiding, ElementName=lstEmployee}" HorizontalAlignment="Left" Margin="259,280,0,0" VerticalAlignment="Top" ToolTip="Der Mitarbeiter wird nicht im Dienstplan angezeigt (beispielsweise wegen längerer Abwesenheit)" Width="211"/>            

        <Button x:Name="btnAdd" Content="Add" Command="{Binding Path=cmdAdd, Mode=TwoWay}" HorizontalAlignment="Left" Height="35" Margin="25,303,0,0" VerticalAlignment="Top" Width="35">
        </Button>
        <Button x:Name="btnEdit" Content="Edit" Command="{Binding Path=cmdEdit}" HorizontalAlignment="Left" Height="35" Margin="70,303,0,0" VerticalAlignment="Top" Width="35">
        </Button>
        <Button x:Name="btnDelete" Content="Delete" Command="{Binding Path=cmdDelete}" HorizontalAlignment="Left" Height="35" Margin="115,303,0,0" VerticalAlignment="Top" Width="35">
        </Button>
        <Button x:Name="btnCancel" Content="Cancel" Command="{Binding Path=cmdCancel}" HorizontalAlignment="Left" Height="35" Margin="391,303,0,0" VerticalAlignment="Top" Width="35">
        </Button>
        <Button x:Name="btnOK" Content="OK" Command="{Binding Path=cmdOK}" HorizontalAlignment="Left" Height="35" Margin="436,303,0,0" VerticalAlignment="Top" Width="35">
        </Button>
    </Grid>
</Window>

my ViewModel: 我的ViewModel:

namespace Models
{
    public class VM_EditEmployee : INotifyPropertyChanged
    {
        #region Propertys
        private ObservableCollection<Common.Employee> mListOfEmployees;
        private ObservableCollection<Common.EmployeeContract> mListOfContracts;
        private ObservableCollection<Common.EmployeeGroup> mListOfGroups;
        private Common.Employee mMasterEmployee;
        private bool isNew;
        private Employee.frmEditEmployee EmpoyeeView;

        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<Common.Employee> ListOfEmployees
        {
            get
            {
                return mListOfEmployees;
            }

            set
            {
                mListOfEmployees = value;
                OnPropertyChanged("ListOfEmployees");
            }
        }
        public ObservableCollection<EmployeeContract> ListOfContracts
        {
            get
            {
                return mListOfContracts;
            }

            set
            {
                mListOfContracts = value;
                OnPropertyChanged("ListOfContracts");
            }
        }
        public ObservableCollection<EmployeeGroup> ListOfGroups
        {
            get
            {
                return mListOfGroups;
            }

            set
            {
                mListOfGroups = value;
                OnPropertyChanged("ListOfGroups");
            }
        }
        public Common.Employee MasterEmployee
        {
            get
            {
                return mMasterEmployee;
            }

            set
            {
                mMasterEmployee = value;
                OnPropertyChanged("MasterEmployee");
            }
        }


        public ICommand cmdAdd { get; set; }
        public ICommand cmdEdit { get; set; }
        public ICommand cmdDelete { get; set; }
        public ICommand cmdCancel { get; set; }
        public ICommand cmdOK { get; set; }

        #endregion

        public VM_EditEmployee(Employee.frmEditEmployee tmpView)
        {
            EmpoyeeView = tmpView;
            cmdAdd = new RelayCommand(o => AddEntry());
            cmdEdit = new RelayCommand(o => EditEntry());
            cmdDelete = new RelayCommand(o => DeleteEntry());
            cmdCancel = new RelayCommand(o => Cancel());
            cmdOK = new RelayCommand(o => SaveEntry());

            ListOfEmployees = Database_Employee.GetListOfEmployee();
            ListOfContracts = Database_Contract.GetListOfContract();
            ListOfGroups = Database_Group.GetListOfGroups();
        }

        protected internal void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
        }

        private void DeleteEntry()
        {
            if (MessageBox.Show("Sure you want to delete?", "Question", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                Database_Employee.DeleteEmployee(MasterEmployee);
                ListOfEmployees = Database_Employee.GetListOfEmployee();
            }
        }

        private void Cancel()
        {

        }

        private void AddEntry()
        {
            isNew = true;
            Common.Employee newEmployee = new Common.Employee()
            {
                Forname = "Max",
                Lastname = "Mustermann",
                Showingname = "Max",
                EmployeeID = 666,
                Birthday = new System.DateTime(1980, 5, 5),
                Loan = "9,50",
                Contract = Database_Contract.GetListOfContract()[0],
                Group = Database_Group.GetListOfGroups()[0],
                Telephone = "012456789",
                EMail = "chris@roedernet.de",
                isHiding = false
            };

            ListOfEmployees.Add(newEmployee);
            MasterEmployee = newEmployee;
        }

        private void EditEntry()
        {
            isNew = false;
        }

        private void SaveEntry()
        {
                if (isNew == true)
                {
                    Database_Employee.CreateEmployee(MasterEmployee);                    
                }
                else                    {
                    Database_Employee.EditEmployee(MasterEmployee);
                }
                ListOfEmployees = Database_Employee.GetListOfEmployee();
            }
            else // Wenn der EditMode nict aktiv ist
            {
                EmpoyeeView.Close();
            }


        }
    }
}

The "MasterEmployee" property is for getting access to the selected item in the ViewModel to save changes in the employee. “ MasterEmployee”属性用于访问ViewModel中的选定项目,以保存员工中的更改。 Everything works fine, the ListBox is filled with data and the details of the selected employee in the ListBox is shown correctly in the textboxes (there are more then just this one, but its not necessary for this question). 一切正常,列表框充满了数据,并且列表框中所选雇员的详细信息正确显示在文本框中(除了这个,还有更多,但这对于这个问题不是必需的)。

When I create a new employee I create a new instance of the class employee, fill it with some placeholder-information and set the reference of the MasterEmployee to this new employee, because I want to edit the new employee in the textboxes of the view. 当我创建新员工时,我会创建类员工的新实例,在其中填充一些占位符信息,并将MasterEmployee的引用设置为此新员工,因为我想在视图的文本框中编辑新员工。 Then I edit the new employee, save the changes and want to go to another employee in the ListView and nothing happens. 然后,我编辑新员工,保存更改,并想转到ListView中的另一位员工,但没有任何反应。 I guess its because when I set the reference of the MasterEmployee, the binding with the ListBox is lost. 我猜是因为当我设置MasterEmployee的引用时,与ListBox的绑定丢失了。

So my question is: How can I solve this problem? 所以我的问题是:我该如何解决这个问题? I want to keep the MVVM pattern, means, for setting the binding via code I need to access the view in the viewmodel and thats not MVVM. 我想保留MVVM模式,即通过代码设置绑定,我需要在viewmodel中访问视图,而并不是MVVM。

Thanks a lot! 非常感谢! Chris 克里斯

I see several issues with the code posted, possibly because it is incomplete: 我看到发布的代码有几个问题,可能是因为它不完整:

  • SelectedItem : You're textboxes etc are binding to SelectedItem but there is no such property on your VM. SelectedItem :您正在将文本框等绑定到SelectedItem,但是您的VM上没有此类属性。 You probably mean to bind to MasterEmployee . 您可能打算绑定到MasterEmployee (note: I would rather name that SelectedItem instead). (注意:我宁愿将其命名为SelectedItem)。 I think this is the root cause of what you are seeing. 我认为这是您所看到的根本原因。
  • When you execute SaveEntry you're probably recreating the list completely. 当执行SaveEntry您可能会完全重新创建列表。 As such MasterEmployee won't be in that list anymore. 因此, MasterEmployee将不再在该列表中。 I think this might lead to further bugs. 我认为这可能会导致进一步的错误。 You're showing a node that is not in the list. 您正在显示不在列表中的节点。

If this doesn't help please provide a complete simple example because the code you posted is incomplete and won't compile. 如果这样做没有帮助,请提供一个完整的简单示例,因为您发布的代码不完整并且无法编译。 Try to narrow down your issue. 尝试缩小问题范围。

Problem solved, it was an issue with my employee class where i had overridden the GetHashCode function to return the employeeID. 问题解决了,这是我的员工类的一个问题,其中我重写了GetHashCode函数以返回employeeID。 This makes the binding brake up when editing the employeeID... thanks for your efforts! 这在编辑employeeID时使绑定停止工作...感谢您的努力!

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

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