0

在这个程序中,我可以通过单击“添加课程”按钮一次添加一个选项卡。理想情况下,选项卡的标题应该是我输入的课程名称,并且选项卡上的 textbox 中的文本应该显示课程名称。

但是,它无法正常运行。当我尝试添加超过 1 个选项卡时,每次它都会给我这个错误消息:

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

此外,它似乎“覆盖”了其他选项卡的文本(只是文本,而不是标题)。例如,如果我添加一个带有标题“a”的选项卡,其文本也是“a”。然后,如果我添加“B”,两个选项卡上的两个文本框都变为“B”。但是,如果我打印出每个选项卡的 Text 属性(在本例中为 MyHomeworkModel),它们分别是“a”和“B”。

我一整天都在调试,但没有运气。任何帮助,将不胜感激!

我的视图(DataContext 设置为 MyHomeworkViewModel):

<Window x:Class="MyHomework__MVVM_.MyHomeworkView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="My Homework" Height="450" Width="800" ResizeMode="CanMinimize">
    <Grid Margin="0,0,10,10">
        <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>
        <Button Content="Add Course" HorizontalAlignment="Left" VerticalAlignment="Top" Width="105" Margin="10,351,0,0" Height="50" Command="{Binding AddCourseCommand}"/>
        <Button Content="Drop Course" HorizontalAlignment="Left" VerticalAlignment="Top" Width="76" Margin="138,379,0,0" Height="22" Command="{Binding DropCourseCommand, UpdateSourceTrigger=PropertyChanged}"/>
        <Button Content="Save HW" HorizontalAlignment="Left" VerticalAlignment="Top" Width="105" Margin="669,351,0,0" Height="50"/>
    </Grid>
</Window>

我的模型:

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));
            }
        }
    }
}

我的视图模型:

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

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

        public MyHomeworkViewModel(MyHomeworkView mainWindow)
        {
            allTabs = new ObservableCollection<MyHomeworkModel>();
            this.mainWindow = mainWindow;
            AddCourseCommand = new AddCourseCommand(this);
            DropCourseCommand = new DropCourseCommand(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 ICommand DropCourseCommand
        {
            get;
            private set;
        }

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

            foreach (MyHomeworkModel item in AllTabs)
            {
                Console.WriteLine(item.Text);
            }
        }

        public bool CanDrop()
        {
            return SelectedTab != null;
        }

        public void RemoveTab()
        {
            DropCourseConfirmation dcc = new DropCourseConfirmation();
            dcc.Owner = mainWindow;
            dcc.ShowDialog();
            if (dcc.drop == true)
            {
                int index = AllTabs.IndexOf(SelectedTab);
                AllTabs.Remove(SelectedTab);

                if (AllTabs.Count > 0)
                {
                    if (index == 0)
                    {
                        SelectedTab = AllTabs[0];
                    }
                    else
                    {
                        SelectedTab = AllTabs[--index];
                    }
                }
                else
                {
                    SelectedTab = null;
                }
            }
        }

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

如果您需要更多代码来帮助我,请告诉我。

4

2 回答 2

0

DataContext的不是你想的那样。阅读那里的错误。它指出“文本”不是一个有效的属性,MyHomeworkViewModel它是真的(与你的相反MyHomeworkModel)。

您需要修改而不是 ItemContainerStyle 而是ItemTemplate使用ContentTemplateItemsSource 中的适当对象作为其DataContext.

此外,您的 TextBox 中的绑定必须是Text="{Binding Text, Mode=TwoWay}",否则它不会修改模型中的属性。

于 2013-01-18T21:04:40.057 回答
0

改变你的

<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="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                        <Grid>
                            <TextBox Text="{Binding Text}" FontSize="16" AcceptsReturn="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                            </TextBox>
                        </Grid>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
于 2013-01-18T21:08:39.557 回答