简体   繁体   中英

wpf help binding data to controls in TabControl

So I have a TabControl with two TabItems, each TabItem has the same controls on it (8 TextBlocks) and will display data under the same bindings as their counterparts on the other TabItem. The xaml and cs code that I have is below, but when I try execute it I get this error.

Items collection must be empty before using ItemsSource.

XAML for TabItem Structure

<TabControl Name="tbcIndividualStats" HorizontalAlignment="Left" Height="652" VerticalAlignment="Top" Width="1338" ItemsSouce="{Binding tabcontrolitems}">
  <!--Template for all tabs (idea is to have them dynamically created eventually)-->
  <!--Content template-->
  <TabControl.ContentTemplate>
    <DataTemplate>
      <Grid>
        <!--Border just holds the stuff-->
        <Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
          <StackPanel Margin="0,0,-1,0">
            <TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
            <TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
            <TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
            <TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
            <TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
            <TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
            <TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
            <TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
          </StackPanel>
        </Border>
      </Grid>
    </DataTemplate>
  </TabControl.ContentTemplate>

  <!--Item Template-->
  <TabControl.ItemTemplate>
    <DataTemplate>
      <Grid>
        <!--Border just holds the stuff-->
        <Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
          <StackPanel Margin="0,0,-1,0">
            <TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
            <TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
            <TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
            <TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
            <TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
            <TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
            <TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
            <TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
          </StackPanel>
        </Border>
      </Grid>
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabItem Header="PlayerName" Background="Transparent" />
  <TabItem Header="PlayerName2" Background="Transparent" />
</TabControl>

C# for Binding Data

public class TabItemContent
{
    public string Venue { get; set; }
    public string TopSpeed { get; set; }
    public string DistRun { get; set; }
    public string TimeLow { get; set; }
    public string TimeMed { get; set; }
    public string TimeHigh { get; set; }
    public string TimeSprint { get; set; }
    public string DistSprint { get; set; }
}

public void foo()
{
//All one line of code
//FileLoadData is a List of another class where all my data is stored
var tabitemcontents = new List<TabItemContent> { new TabItemContent { Venue = FileLoadData[0].Venue, TopSpeed = FileLoadData[0].TopSpeed.ToString(), DistRun = FileLoadData[0].TotalDistance.ToString(), TimeLow = FileLoadData[0].TimeLow.ToString(),
        TimeMed = FileLoadData[0].TimeMed.ToString(), TimeHigh = FileLoadData[0].TimeHigh.ToString(), TimeSprint = FileLoadData[0].TimeSprint.ToString(), DistSprint = "null"},
        new TabItemContent { Venue = FileLoadData[1].Venue, TopSpeed = FileLoadData[1].TopSpeed.ToString(), DistRun = FileLoadData[1].TotalDistance.ToString(), TimeLow = FileLoadData[1].TimeLow.ToString(),
        TimeMed = FileLoadData[1].TimeMed.ToString(), TimeHigh = FileLoadData[1].TimeHigh.ToString(), TimeSprint = FileLoadData[1].TimeSprint.ToString(), DistSprint = "null"}};

//Error here, supposed to add to the TabItems
tbcIndividualStats.ItemsSource = tabitemcontents;
}

I've been looking for a solution for ages and I can't get one to work. I just need to bind that data from FileLoadData[0] and FileLoadData[1] to the two TabItems respectivly.

I would adopt a different strategy:

Add to your model, the name that you want to show in the Header of the Tabitem:

public class TabItemContent
{
    public string PlayerName {get; set;}  // New Property for the Tabitem Header
    public string Venue { get; set; }
    public string TopSpeed { get; set; }
    public string DistRun { get; set; }
    public string TimeLow { get; set; }
    public string TimeMed { get; set; }
    public string TimeHigh { get; set; }
    public string TimeSprint { get; set; }
    public string DistSprint { get; set; }
}

Then i'd change the Xaml considering this new attribute:

<TabControl Name="tbcIndividualStats" HorizontalAlignment="Left" Height="652" VerticalAlignment="Top" Width="1338">
  <!--Template for all tabs (idea is to have them dynamically created eventually)-->
  <!--Content template-->
  <TabControl.ContentTemplate>
    <DataTemplate>
      <Grid>
        <!--Border just holds the stuff-->
        <Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
          <StackPanel Margin="0,0,-1,0">
            <TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
            <TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
            <TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
            <TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
            <TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
            <TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
            <TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
            <TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
          </StackPanel>
        </Border>
      </Grid>
    </DataTemplate>
  </TabControl.ContentTemplate>

  <!--Item Template-->
  <TabControl.ItemTemplate>
    <DataTemplate>
        <Border>
            <Textblock = Text="{Binding PlayerName}"/>
        </Border>
    </DataTemplate>
  </TabControl.ItemTemplate>
</TabControl>

EDIT : the item template is the template for the tabitem button and content template is for its content. Some references here: TabItem.ItemTemplate vs TabItem.ContentTemplate

I've also removed the two TabItem defined inside TabControl.

Remember also to set the ItemsSource -> if you set it in code-behind, remove this line: ItemsSouce="{Binding tabcontrolitems}" .

Remove these <TabItem> elements from the XAML:

<TabItem Header="PlayerName" Background="Transparent" />
<TabItem Header="PlayerName2" Background="Transparent" />

You can't both add individual items to the TabControl and use an ItemsSource . It's one way or the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM