C# ListView SelectedItem不使用MVVM灯光从视图模型更新

C# ListView SelectedItem不使用MVVM灯光从视图模型更新,c#,wpf,listview,mvvm-light,selecteditem,C#,Wpf,Listview,Mvvm Light,Selecteditem,我正在使用MVVM light将ListView绑定到ViewModel上的ItemSource。当对ViewModel上的属性进行更改时,SelectedItem不会在视图中更新 XAML: 视图模型: public Model.V\u PWT\u APP\u所有选定应用 { 获取{返回此。\u selectedApp;} 集合{ 这是。\ u选择的App=值; RaisePropertyChanged(()=>selectedApp); } } 从视图中选择项目将更新ViewModel,并

我正在使用MVVM light将ListView绑定到ViewModel上的ItemSource。当对ViewModel上的属性进行更改时,SelectedItem不会在视图中更新

XAML:

视图模型:

public Model.V\u PWT\u APP\u所有选定应用
{
获取{返回此。\u selectedApp;}
集合{
这是。\ u选择的App=值;
RaisePropertyChanged(()=>selectedApp);
}
}


从视图中选择项目将更新ViewModel,并更新从SelectedItem派生其数据的所有控件。双向绑定似乎不起作用。

如果要继续使用INotified属性更改界面,应按照以下文档中的说明设置代码:

由于您似乎不是在更改属性,而是在更改项目并通知ItemsSource,因此更好的方法是实现IObserver/IObservable接口。这稍微简单一点,并且在模型自己的类中保持整洁和可管理的更新。下面是一个可能的代码示例:

public class App: IObservable<App>     //where the model class is the IObserver.

{

private App app;
internal App
List<IObserver<App>> Observers = new List<IObserver<App>>();

{

     get:
            {

                 return app;
            }

     set:

            {
                 app = value;
                 try
                 {
                      foreach (var observer in Observers) observer.OnNext(value);
                      foreach (var observer in Observers) observer.OnCompleted();
                 }
                 catch(Exception ex)
                 {
                      foreach (var observer in Observers) observer.OnError(ex);
                      throw;
                 }
            }
}
public-class-App:IObservable//其中模型类是IObserver。
{
私人应用程序;
内部应用程序
列表观察员=新列表();
{
获取:
{
返回应用程序;
}
设置:
{
app=价值;
尝试
{
foreach(观察者中的var观察者)observer.OnNext(值);
foreach(观察者中的var观察者)observer.OnCompleted();
}
捕获(例外情况除外)
{
foreach(观察员中的var观察员)observer.OnError(ex);
投掷;
}
}
}
对于viewModel:

public Model.V_PWT_APP_ALL selectedApp: IOberver<App>
{
     List<Control> ControlsToBeUpdated = new List<Control>() //Each control that needs updated should implement and interface that has an .Update(type T) method where T is whatever value needs updated.
     public void OnCompleted()
     {
          //...notify taskBar, etc. 
     }

     public void OnError(Exception error)
     {
         //handle exception, update log, etc.
     }

     public void OnNext(object value)
     {
         foreach (var control in ControlsToBeUpdated) control.Update(value);
     }
}
public Model.V\u PWT\u APP\u所有选择APP:IOberver
{
List ControlsToBeUpdated=new List()//每个需要更新的控件都应该实现一个具有.Update(类型T)方法的接口,其中T是需要更新的任何值。
未完成的公共无效()
{
//…通知任务栏等。
}
公共无效OnError(异常错误)
{
//处理异常、更新日志等。
}
public void OnNext(对象值)
{
foreach(ControlsToBeUpdated中的var控件)control.Update(值);
}
}

起初,这可能看起来很乏味,但它帮助我很好地最小化和管理ItemsSource中的更新和bug。最后,我发现在使用ListView ItemsSource时,控制scrollView相当乏味,并且在简单地使用ListView.Items.Insert(…)时运气更好方法,因为当更新ItemsSource并选择scrollview时,它经常抛出OutOfRange异常。这在MVVM中可能很难调试。但是,这是另一个主题。我希望这会有所帮助。

我发现问题在于SelectedItem绑定。我发现我没有正确选择项目。我切换到using SelectedIndex并找到正确的索引和绑定正如预期的那样工作。

有趣的方法。但是,这里的ItemsSource似乎不是问题。问题出在SelectedItem:
SelectedItem=“{binding selectedApp,Mode=TwoWay}”
我正在更新selectedApp,并且正在进行RaiseProperty更改,但是所选项目没有更改。我相信您需要添加一个偶数来处理代码中更改的选择。您似乎绑定到加载时选择的应用程序,而不是在ListView中单击的应用程序。而不是使用Model.V_PWT_app_ALL selec的settertedApp,创建一个方法来处理C代码中更改的选择,并使用(发件人为ListView)将RaisePropertyChanged(()=>selectedApp)放入该方法中。SelectedItem。将事件添加到SelectionChanged=“ListView\U SelectionChanged”中/>XAML应该是我已经有了一个SelectionChanged事件的处理程序``当您使用UI并单击(选择)时,这会起作用一个项目。从我的视图到视图模型的绑定起作用。问题是如何让视图根据视图模型中的更改选择一个项目。IObserver/IObservable模式是为基于推送的命令创建的。您的视图模型需要包含一个模型视图列表,以便在更改时推送更新。标准格式已包含在在setter上,您只需调用ViewModels.OnNext(object o)方法即可更新ModelView。NotifyPropertyChanged不适合从ViewModel切换到ModelView,但可以使其正常工作。IObserver/IObservable更好。请参阅