Когда я передаю параметр в MainViewModel, содержимое TreeView не отображается.
Я новичок в C # и MVVM. Когда я создал MainViewModel и TreeView, они работали нормально. Затем, теперь я хотел бы выбрать определенные тестовые элементы из всего списка и показать только те TreeView. Отборочная часть была сделана независимо, и сейчас я пытаюсь объединить их. Однако, когда я передаю выбранный список тестов в MainViewModel, TreeView перестает показывать содержимое. Если я не передам параметр, содержимое появится снова.
Я также добавил простой TreeView без каких-либо привязок, все написано на XAML. Содержимое отображается независимо от того, передан ли параметр или нет. Итак, я думаю, что это не проблема TreeView, а проблема привязки.
Вот мои полные коды:
ViewModels / MainViewModel.cs
using TwoListBoxes.Models;
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace TwoListBoxes.ViewModels
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
} // <= To show the contents, comment these lines out
public MainViewModel(List<string> selectedTestList) // <= To show the contents, comment these lines out
{ // <= To show the contents, comment these lines out
// ### I'd like to use selectedTestList as a search key here ###
var TotalModel = new TotalModel(
failNum: 123,
failRate: 45.6
);
var TotalViewModel = new TotalViewModel(TotalModel);
TotalViewModel.AddTotal(TotalModel);
Totals.Add(TotalViewModel);
}
public ObservableCollection<TotalViewModel> Totals { get; }
= new ObservableCollection<TotalViewModel>();
}
}
ViewModels / TotalViewModel.cs
using TwoListBoxes.Models;
using System.Collections.ObjectModel;
namespace TwoListBoxes.ViewModels
{
public class TotalViewModel : ViewModelBase<TotalModel>
{
public TotalViewModel(TotalModel model) : base(model)
{
}
public ObservableCollection<TotalViewModel> Totals { get; }
= new ObservableCollection<TotalViewModel>();
public void AddTotal(TotalModel total)
{
var viewModel = new TotalViewModel(total);
Totals.Add(viewModel);
}
public string TotalName => $"{Model.FailNum} {Model.FailRate}";
}
}
ViewModels / ViewModelBase.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
namespace TwoListBoxes.ViewModels
{
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public abstract class ViewModelBase<TModel> : ViewModelBase
where TModel : class
{
private TModel _model;
public ViewModelBase(TModel model)
=> _model = model;
public TModel Model
{
get => _model;
set
{
if (ReferenceEquals(_model, value))
{
return;
}
_model = value;
OnPropertyChanged();
}
}
}
}
Models / TotalModel.cs
namespace TwoListBoxes.Models
{
public class TotalModel
{
public TotalModel(
int failNum,
double failRate
)
{
FailNum = failNum;
FailRate = failRate;
}
public int FailNum { get; }
public double FailRate { get; }
}
}
Views / CalcWindow.xaml.cs
using TwoListBoxes.ViewModels;
using System.Collections.Generic;
using System.Windows;
namespace TwoListBoxes.Views
{
public partial class CalcWindow : Window
{
public CalcWindow()
{
InitializeComponent();
}
public CalcWindow(List<string> selectedTestList) : this()
{
// shows the TreeView
//new MainViewModel();
// does NOT show the TreeView
new MainViewModel(selectedTestList);
}
}
}
Views / CalcWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:TwoListBoxes.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="TwoListBoxes.Views.CalcWindow"
Title="TreeView" Width="1000" Height="512">
<Window.DataContext>
<viewModels:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<CollectionViewSource x:Key="ViewSource1" Source="{Binding Partials}"/>
<CollectionViewSource x:Key="ViewSource2" Source="{Binding Totals}"/>
<CompositeCollection x:Key="CombinedCollection">
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource1}}" />
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource2}}" />
</CompositeCollection>
</Window.Resources>
<Grid>
<StackPanel Margin="0,250,0,0">
<TreeView ItemsSource="{StaticResource CombinedCollection}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type viewModels:TotalViewModel}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Model.FailNum}" Margin="5,0" />
<TextBlock Text="{Binding Path=Model.FailRate}" Margin="5,0" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</StackPanel>
<!--<StackPanel>
<TreeView>
<TreeViewItem Header="Item1-1">
<TreeViewItem Header="Item1-1-1" />
<TreeViewItem Header="Item1-1-2" />
</TreeViewItem>
<TreeViewItem Header="Item1-2">
<TreeViewItem Header="Item1-2-1" />
</TreeViewItem>
</TreeView>
</StackPanel>-->
</Grid>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using TwoListBoxes.Views;
namespace TwoListBoxes
{
public partial class MainWindow : Window
{
List<string> SelectedTestList = new List<string>() { "Test_1", "Test_2" };
public MainWindow()
{
InitializeComponent();
}
private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
new CalcWindow(SelectedTestList).Show();
}
}
}
MainWindow.xaml
<Window x:Class="TwoListBoxes.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test Selection" Height="375" Width="700">
<Grid>
<ListBox Margin="91,32,0,40" Name="LeftListBox" HorizontalAlignment="Left" Width="168" Background="AntiqueWhite" />
<ListBox Margin="0,31,89,41" Name="RightListBox" HorizontalAlignment="Right" Width="176" Background="AntiqueWhite"/>
<Button Name="AddButton" Height="27" Margin="292,97,294,0" VerticalAlignment="Top"
>Add >></Button>
<Button Name="RemoveButton" Margin="292,0,294,100"
Height="28" VerticalAlignment="Bottom"><< Remove</Button>
<Button Name="ConfirmButton" Content="Confirm" Margin="292,0,294,10" VerticalAlignment="Bottom" Click="ConfirmButton_Click"/>
</Grid>
В первом окне, пожалуйста, нажмите кнопку «Подтвердить». («Test_1» и «Test_2» уже жестко запрограммированы как элементы SelectedTestList.) Вы НЕ увидите никакого содержимого TreeView.
Чтобы показать содержимое, закомментируйте конструкторы MainViewModel и попытайтесь НЕ передавать параметр в CalcWindow. Вы увидите «123 45.6» как содержимое TreeView (на этот раз они жестко запрограммированы, но на самом деле эти числа должны генерироваться после того, как SelectedTestList используется в качестве ключа поиска).
Почемутакое поведение с / без параметра в конструкторе? Есть ли обходной путь? Заранее спасибо.