我的列表框有问题,因为更新绑定到的列表时它没有更新。我已经看过许多相同的问题,但是没有一个答案能解决我的问题。我的情况是我有一个ComboBox,当选择一个选项时,我的ListBox将基于ComboBox选择显示选项。我知道绑定到ListBox的列表正在更新,但是项目没有显示在列表上。如果我在列表的ViewModel类的声明上手动添加了一个项目,则该项目的出现比我想的要多,但这不是我想要的(或者也许是我从错误的角度看到的)。到目前为止,这是我的代码:
用于我的ComboBox的VM以及用于更新ListBox的调用:
public class SelectorEventosViewModel : ObservableCollection<SelectorEvents>,INotifyPropertyChanged
{
private SelectorEvents _currentSelection;
public SelectorEventosViewModel()
{
PopulaSelectorEvents();
}
private void PopulaSelectorEvents()
{
Add(new SelectorEvents {Key = "evtInfoEmpregador", Value = "S1000"});
Add(new SelectorEvents {Key = "evtTabEstab", Value = "S1005"});
Add(new SelectorEvents {Key = "evtTabRubricas", Value = "S1010"});
}
public SelectorEvents CurrentSelection
{
get => _currentSelection;
set
{
if (_currentSelection == value)
return;
_currentSelection = value;
OnPropertyChanged(nameof(CurrentSelection));
ValueChanged(_currentSelection.Key);
}
}
//Here I detect selectiong and then call for the Update in my ListBox VM
private void ValueChanged(string value)
{
EventFilesViewModel.Instance.GetFiles(value);
}
protected override event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是ListBox VM的代码:
public class EventFilesViewModel : ObservableCollection<EventFiles>
{
private static EventFilesViewModel _instance = new EventFilesViewModel();
public static EventFilesViewModel Instance => _instance ?? (_instance = new EventFilesViewModel());
private string[] _filesList;
//This would be my Update function, based on the ComboBox selection I would show some files in my ListBox, but it's not
public void GetFiles(string ptr)
{
_filesList = Directory.GetFiles(@"\\mp-2624/c$/xampp/htdocs/desenv2/public/esocial/eventos/aguardando/");
Clear();
foreach (string file in _filesList)
{
var r = new Regex(ptr, RegexOptions.IgnoreCase);
var tempFiles = new EventFiles {Key = file, Value = file.Split('/')[9]};
if (r.Match(file).Success)
{
Add(tempFiles);
}
}
OnPropertyChanged(nameof(EventFilesViewModel));
}
protected override event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我的模型SelectorEvents和FileEvents都实现了INotifyPropertyChanged。
我的XAML:
<ComboBox DataContext="{StaticResource ResourceKey=SelectorEventosViewModel}" Name="EventoBox" FontSize="20" SelectedIndex="0" Margin="20 10" Width="150"
ItemsSource="{StaticResource ResourceKey=SelectorEventosViewModel}"
DisplayMemberPath="Value"
SelectedItem="{Binding CurrentSelection}"
IsSynchronizedWithCurrentItem="True"/>
<ListBox DataContext="{StaticResource ResourceKey=EventFilesViewModel}"
Grid.Column="0" Name="EventoListBox" FontSize="20" Margin="10 10"
HorizontalAlignment="Stretch"
ItemsSource="{StaticResource ResourceKey=EventFilesViewModel}"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Value">
谢谢。
答案 0 :(得分:0)
所以我不确定您打算如何进行这项工作,但是这里有一个解决方案,它是更多的MVVM。
实质上,我们将两个VM都折叠到MainWindowVm中,该MainWindowVm处理两者之间的穿梭消息。这样,您的子虚拟机就可以保持彼此独立,从而可以在线下进行更多配置。
根据我的测试,第二条记录上与ItemSource的绑定未成功(我在确认EventFilesViewModel已更新之后添加了一个按钮,并在运行时检查了ItemSource的值)。
EventFilesViewModel
public class EventFilesViewModel : INotifyPropertyChanged
{
public ObservableCollection<EventFiles> EventFiles { get; } = new ObservableCollection<EventFiles>();
private string[] _filesList;
//This would be my Update function, based on the ComboBox selection I would show some files in my ListBox, but it's not
public void GetFiles(string ptr)
{
_filesList = Directory.GetFiles(@"\\mp-2624/c$/xampp/htdocs/desenv2/public/esocial/eventos/aguardando/");
EventFiles.Clear();
foreach (string file in _filesList)
{
var r = new Regex(ptr, RegexOptions.IgnoreCase);
var tempFiles = new EventFiles { Key = file, Value = file.Split('/')[9] };
if (r.Match(file).Success)
{
EventFiles.Add(tempFiles);
}
}
OnPropertyChanged(nameof(EventFilesViewModel));
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
SelectorEventosViewModel
public class SelectorEventosViewModel : INotifyPropertyChanged
{
public ObservableCollection<SelectorEvents> SelectorEvents { get; set; } = new ObservableCollection<SelectorEvents>();
private SelectorEvents _currentSelection;
public SelectorEventosViewModel()
{
PopulaSelectorEvents();
}
private void PopulaSelectorEvents()
{
SelectorEvents.Add(new SelectorEvents { Key = "evtInfoEmpregador", Value = "S1000" });
SelectorEvents.Add(new SelectorEvents { Key = "evtTabEstab", Value = "S1005" });
SelectorEvents.Add(new SelectorEvents { Key = "evtTabRubricas", Value = "S1010" });
}
public SelectorEvents CurrentSelection
{
get => _currentSelection;
set
{
if (_currentSelection == value)
return;
_currentSelection = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindowVm.cs
public class MainWindowVm : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public SelectorEventosViewModel SelectorEventosViewModel { get; } = new SelectorEventosViewModel();
public EventFilesViewModel EventFilesViewModel { get; } = new EventFilesViewModel();
public MainWindowVm()
{
// CRITICAL--ensures that your itemsource gets updated
SelectorEventosViewModel.PropertyChanged += SelectorEventosViewModel_PropertyChanged;
}
private void SelectorEventosViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// CRITICAL--ensures that your itemsource gets updated
EventFilesViewModel.GetFiles(SelectorEventosViewModel.CurrentSelection.Key);
}
}
MainWindow.xaml
<Window x:Class="_52370275.MainWindow"
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:_52370275"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="800"
d:DataContext="{d:DesignInstance local:MainWindowVm}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox
Name="EventoBox"
FontSize="20"
SelectedIndex="0"
Margin="20 10"
Width="150"
Grid.Row="0"
ItemsSource="{Binding SelectorEventosViewModel.SelectorEvents}"
DisplayMemberPath="Value"
SelectedItem="{Binding SelectorEventosViewModel.CurrentSelection}"
IsSynchronizedWithCurrentItem="True" />
<ListBox Grid.Column="0"
Name="EventoListBox"
FontSize="20"
Margin="10 10"
Grid.Row="1"
HorizontalAlignment="Stretch"
ItemsSource="{Binding EventFilesViewModel.EventFiles}"
IsSynchronizedWithCurrentItem="True"
DisplayMemberPath="Value" />
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowVm();
}
}
总而言之,这使您可以在代码后方为初始组合框定义静态值,并更新列表框itemsource。