为什么这些选项卡似乎共享同一个文本框?
本文关键字:同一个 共享 文本 选项 为什么 | 更新日期: 2023-09-27 17:54:08
我在xaml中定义了我的UI,下面是我的代码:
<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>
当我运行程序时。我可以毫无问题地添加许多标签。标题是不同的,但每当我改变其中一个选项卡中的文本框的内容时,其他选项卡中的所有文本框都更改为相同的内容(似乎它们都共享相同的文本框,或绑定到相同的源,这很奇怪)。
我在定义UI时犯了错误吗?请帮助我,并提前感谢。
这是我的模型,非常简单:
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));
}
}
}
}
编辑:刚刚注意到我收到了这条消息:
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')
我想我知道它为什么抱怨了。我的文本属性是MyHomeworkModel而不是MyHomeworkViewModel…但是为什么我在MyHomeworkModel中将header绑定到header属性呢?
我的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();
}
}
}
似乎你的模型实现
ObservableCollection<MyHomeworkModel>.
删除这个基类,它应该可以工作。
编辑:
您需要更改:
AddCourseCommand = new AddCourseCommand(this);
下载DelegateCommand AddCourseCommand = new DelegateCommand(AddNewTab);
编辑:你从你的UI中剪切你的ViewModel。你复制一个实例到你的命令中,然后调用那个Copy add。这是错误的,属性是你的错。我真的建议你使用DelegateCommand,这可能会修复它。
To your guess:
我想我知道为什么它在抱怨。我的文本属性是MyHomeworkModel而不是MyHomeworkViewModel…但是为什么我在MyHomeworkModel中将header绑定到header属性呢?
这是正确的,你的属性是在MyHomeworkModel
,而不是在MyHomeworkViewModel
,你绑定到一个包含MyHomeworkModel
s的列表。现在你添加一个新项目,你的绑定将设置在最底层。在这种情况下,在MyHomeworkModel
的实例中,而不是在MyHomeworkViewModel