Почему эти вкладки, похоже, имеют одно и то же текстовое поле?

117
16

Я определил свой пользовательский интерфейс в xaml, а ниже - мой код:

<TabControl HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="764" Margin="10,10,0,0" ItemsSource="{Binding AllTabs}" SelectedItem="{Binding SelectedTab}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="Content">
<Setter.Value>
<Grid>
<TextBox Text="{Binding Text}" FontSize="16" AcceptsReturn="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</TextBox>
</Grid>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="20"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>

Когда я запускал свою программу. Я мог бы добавить много вкладок без проблем. Заголовки разные, но всякий раз, когда я меняю содержимое текстового поля на одной из вкладок, все текстовые поля на других вкладках меняются на один и тот же контент (похоже, все они используют одно и то же текстовое поле или привязку к тому же самому источнику, что и странно),

Я сделал ошибку, определяя интерфейс? Пожалуйста, помогите мне и спасибо заранее.

Это моя модель, очень простая:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace MyHomework__MVVM_
{
class MyHomeworkModel : INotifyPropertyChanged
{
private string header, text;
public event PropertyChangedEventHandler PropertyChanged;

public string Header
{
get
{
return header;
}
set
{
header = value;
OnPropertyChanged("Header");
}
}

public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
}
}

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

И моя viewmodel, которая по-прежнему очень проста:

using MyHomework;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;

namespace MyHomework__MVVM_
{
class MyHomeworkViewModel : INotifyPropertyChanged
{
private ObservableCollection<MyHomeworkModel> allTabs;
private MyHomeworkModel selectedTab;
public event PropertyChangedEventHandler PropertyChanged;

public MyHomeworkViewModel()
{
allTabs = new ObservableCollection<MyHomeworkModel>();
selectedTab = new MyHomeworkModel();
AddCourseCommand = new AddCourseCommand(this);
}

public ObservableCollection<MyHomeworkModel> AllTabs
{
get
{
return allTabs;
}
set
{
allTabs = value;
OnPropertyChanged("AllTabs");
}
}

public MyHomeworkModel SelectedTab
{
get
{
return selectedTab;
}
set
{
selectedTab = value;
OnPropertyChanged("SelectedTab");
}
}

public ICommand AddCourseCommand
{
get;
private set;
}

public void AddNewTab()
{
NewCourseName ncn = new NewCourseName();
ncn.ShowDialog();
if (ncn.courseName != null)
{
MyHomeworkModel newTab = new MyHomeworkModel();
newTab.Header = ncn.courseName;
newTab.Text = ncn.courseName;
AllTabs.Add(newTab);
SelectedTab = newTab;
}
}

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

EDIT: Только что заметил, что я получил это сообщение:

System.Windows.Data Error: 40 : BindingExpression path error: 'Text' property not found on 'object' ''MyHomeworkViewModel' (HashCode=31265986)'. BindingExpression:Path=Text; DataItem='MyHomeworkViewModel' (HashCode=31265986); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')

Кажется, я знаю, почему он жалуется. Свойство My Text - это MyHomeworkModel, а не MyHomeworkViewModel... но почему это прекрасно, если я привязываю заголовок к свойству Header в MyHomeworkModel?

Мой класс AddCourseCommand:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MyHomework__MVVM_
{
class AddCourseCommand : ICommand
{
private MyHomeworkViewModel viewModel;

public AddCourseCommand(MyHomeworkViewModel viewModel)
{
this.viewModel = viewModel;
}

public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}

public bool CanExecute(object parameter)
{
return true;
}

public void Execute(object parameter)
{
viewModel.AddNewTab();
}
}
}

спросил(а) 2021-01-25T16:20:53+03:00 4 месяца, 3 недели назад
1
Решение
116

Кажется, что ваш вариант модели

ObservableCollection<MyHomeworkModel>.

Удалите этот базовый класс, и он должен работать.

Изменить:

Ваша потребность изменить:

       AddCourseCommand = new AddCourseCommand(this);

к

Загрузить делегат

       AddCourseCommand = new DelegateCommand(AddNewTab);

Редактировать:

Вы вырезаете ViewModel из своего пользовательского интерфейса. Вы копируете экземпляр в свою команду и вызываете этот экземпляр Copy. Это неправильно и свойство Your Fault. Я действительно советую вам использовать DelegateCommand, возможно, это исправить.

По вашему мнению:

думаю, я знаю, почему он жалуется. Свойство My Text - это MyHomeworkModel, а не MyHomeworkViewModel... но почему это прекрасно, если я привязываю заголовок к свойству Header в MyHomeworkModel?

Правильно, что ваше свойство находится в MyHomeworkModel а не в MyHomeworkViewModel вы MyHomeworkViewModel к списку, содержащему MyHomeworkModel. Теперь вы добавляете новый элемент, который привязка будет установлена на самом низком уровне. В этом случае в вашем представлении MyHomeworkModel а не в MyHomeworkViewModel

ответил(а) 2021-01-25T16:20:53+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема