DataTemplate基于DataType无法正常工作并导致其他问题

时间:2014-04-10 23:21:03

标签: c# wpf datatemplate

我有一个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一边。一个用于属性,一个用于Tennants。当我将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对象。我需要改变什么?我的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课程的其余部分。此外,我的选项卡是具有关闭按钮的自定义选项卡,当我单击tabcontrol旁边的其中一个tennant listboxitems时,它会打开一个空的可关闭选项卡。侧面的Property listboxitems打开了一个完全可关闭的选项卡。然后,我可以关闭属性选项卡,但不能关闭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添加了上下文,并将INotifyPropertyChanged添加到上面更新的Tennant类中。我也忘了添加两个`DataTemplates是分开的这一事实。由GridSplitter分隔。

编辑4:我仍然在寻找这个问题的答案,因为我的问题仍然存在,尽管我已尽最大努力实施了所有建议的答案。< / p>

2 个答案:

答案 0 :(得分:1)

您需要制作Tennant班级工具INotifyPropertyChanged。否则,在支持类中所做的更改将不会反映在UI中,这听起来可能是您的问题。

答案 1 :(得分:1)

您为DataTemplates显示两个不同的隐式Tennant,但不是您宣布它们的位置。如果它们一起结束了范围(或者两者都没有在范围内),那么你可能会得到一个你不期望的那个(或者没有模板)。