基于DataType的DataTemplate不起作用并导致其他问题
本文关键字:其他 问题 不起作用 DataType DataTemplate 基于 | 更新日期: 2023-09-27 17:57:53
我有一个TabControl
,它的ItemsSource
绑定到对象类型的ObservableCollection
。我这样做的唯一原因是,我可以把Property和Tennant(请忽略拼写错误的)类都放在这个列表中。我的TabControl
需要根据类型有两个不同的选项卡。到目前为止,我拥有的是:
<view:CustomTabControl ItemsSource="{Binding OpenTabs}" Grid.Column="1" x:Name="Tabs">
<view:CustomTabControl.Resources>
<DataTemplate DataType="{x:Type model:Tennant}">
<ScrollViewer>
<Grid>
<TextBlock Text="{Binding name}"/>
</Grid>
</ScrollViewer>
</DataTemplate>
<DataTemplate DataType="{x:Type model:Property}">
<ScrollViewer>
<Grid MinWidth="350">
<!-- All of the stuff that works for the Property layout in here -->
</Grid>
</ScrollViewer>
</DataTemplate>
</view:CustomTabControl.Resources>
</view:CustomTabControl>
它非常适合Property类,但不适合Tennant类。此外,我有一个不得不ListBox
的侧面。一个用于房地产,一个用于坦南特。当我将Tennant添加到Tennant的列表中时,它会显示在那里,但不会显示我指定的Tennant名称,如下所示:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Margin="10,5" Text="Properties" FontSize="16"/>
<ListBox x:Name="propertiesList" ItemsSource="{Binding Properties, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type model:Property}">
<TextBlock Text="{Binding title}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Margin="10,5" Text="Tennants" FontSize="16"/>
<ListBox x:Name="tennantsList" ItemsSource="{Binding Tennants, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type model:Tennant}">
<TextBlock Text="{Binding name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</ScrollViewer>
据我所见,Tennant类与Property类几乎完全相同,当然除了它存储的信息之外,但似乎没有任何东西与Tennant对象正确绑定。我需要更改什么?我的坦南特课有什么问题吗?或者我的xaml有什么问题吗?以下是Tennant类,转述如下,供参考:
[Serializable]
public class Tennant : ISerializable, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool current;
private string name;
private string phone;
private string email;
private string occupation;
public bool Current { get { return current; } set { current = value; OnPropertyChanged("Current"); } }
public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } }
public string Phone { get { return phone; } set { phone = value; OnPropertyChanged("Phone"); } }
public string Email { get { return email; } set { email = value; OnPropertyChanged("Email"); } }
public string Occupation { get { return occupation; } set { occupation = value; OnPropertyChanged("Occupation"); } }
public Tennant()
{
}
public Tennant(bool current, string name, string phone, string email, string occupation)
{
this.Current = current;
this.Name = name;
this.Phone = phone;
this.Email = email;
this.Occupation = occupation;
}
private void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
public override string ToString()
{
return "" + Current + " " + Name + " " + Phone + " " + Email + " " + Occupation;
}
public Tennant(SerializationInfo info, StreamingContext context)
{
this.Current = (bool)info.GetValue("Current", typeof(bool));
this.Name = (string)info.GetValue("Name", typeof(string));
this.Phone = (string)info.GetValue("Phone", typeof(string));
this.Email = (string)info.GetValue("Email", typeof(string));
this.Occupation = (string)info.GetValue("Occupation", typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Current", this.Current);
info.AddValue("Name", this.Name);
info.AddValue("Phone", this.Phone);
info.AddValue("Email", this.Email);
info.AddValue("Occupation", this.Occupation);
}
}
编辑:以下是仅供参考的属性对象:
public class Property : ISerializable
{
public string address { get; set; }
public string city { get; set; }
public string postcode { get; set; }
// ...
public Property()
{
// ...
}
public string toString()
{
return title;
}
public bool hasPhotos()
{
return false;
}
public bool hasTennant()
{
return false;
}
public void addTennant(Tennant tennant)
{
tennants.Add(tennant);
}
public void addPhoto(Photo photo)
{
photos.Add(photo);
}
public void addIssue(Problem issue)
{
issues.Add(issue);
}
public Property(SerializationInfo info, StreamingContext context)
{
// ...
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// ...
}
}
我的代码出了什么问题?因为经过几个小时的搜寻,我什么也找不到。提前谢谢。
编辑2:我添加了Tennant类的其余部分。此外,我的选项卡是带有关闭按钮的自定义选项卡,当我单击选项卡控件旁边的一个tennant列表框项目时,它会打开一个空的可关闭选项卡。侧面的属性列表框项目会打开一一个完全可关闭的选项卡。然后,我可以关闭属性选项卡,但不能关闭tennant选项卡。以下是我添加到OpenTabs对象ObservableCollection的代码:
// Inside the Constructor
OpenTabs = new ObservableCollection<Object>();
EventManager.RegisterClassHandler(typeof(ListBoxItem),
ListBoxItem.MouseLeftButtonDownEvent,
new RoutedEventHandler(this.OnMouseLeftButtonDown));
private void OnMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
ListBoxItem selected = sender as ListBoxItem;
try
{
string t = (selected.Content as Property).title;
Property cur = selected.Content as Property;
OpenProperty(cur);
}
catch (NullReferenceException nre)
{
Tennant cur = selected.Content as Tennant;
OpenTennant(cur);
}
}
// This method opens a new tab with a Property's details in it
private void OpenProperty(Property property)
{
this.HomeView.Visibility = System.Windows.Visibility.Hidden;
this.TabbedView.Visibility = System.Windows.Visibility.Visible;
MainWindow.OpenTabs.Add(property);
this.Tabs.SelectedIndex = MainWindow.OpenTabs.IndexOf(property);
}
// This method opens a new tab with a Tennant's details in it
private void OpenTennant(Tennant tennant)
{
this.HomeView.Visibility = System.Windows.Visibility.Hidden;
this.TabbedView.Visibility = System.Windows.Visibility.Visible;
MainWindow.OpenTabs.Add(tennant);
this.Tabs.SelectedIndex = MainWindow.OpenTabs.IndexOf(tennant);
}
希望能有所帮助。问问你是否想要更多。
编辑3:现在我已经向xaml添加了上下文,还向上面更新的Tennant类添加了INotifyPropertyChanged
。我还忘了添加一个事实,即两个`DataTemplates是分开的。如在中用GridSplitter分隔。
编辑4:我仍在寻找这个问题的答案,因为我的问题仍然存在,尽管我已经尽我所能实现了所有建议的答案。
您需要使Tennant
类实现INotifyPropertyChanged
。否则,在支持类中所做的更改将不会反映在UI中,这听起来可能是您的问题。
您为Tennant
显示了两个不同的隐式DataTemplates
,但不是在声明它们的位置。如果它们最终都在范围内(或者都不在范围内),您可能会得到一个您不期望的(或者没有模板)。