В моем приложении есть TabControl. Я хотел бы иметь столько TabItems, сколько статей есть в моем словаре.

Вот мой словарь:

public Dictionary<string , ObservableCollection<PerformanceCounter>> Counters
{
    get { return _Counters; }
}
Dictionary<string, ObservableCollection<PerformanceCounter>> _Counters = new Dictionary<string , ObservableCollection<PerformanceCounter>>();

Каждая запись имеет строковый ключ и ObservableCollection объектов PerformanceCounter. Важным является тот факт, что каждый объект PerformanceCounter имеет свойства: CounterName и InstanceName - мне понадобятся эти два для их отображения.

Теперь к моему XAML:

<TabItem Header="Memory">
    <Grid Name="RAMGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition  Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox Name="RAMListBox" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" ItemsSource="{Binding Memory, Mode=OneWay}" SelectionMode="Multiple" BorderThickness="1" BorderBrush="#FF8B8B8B" SelectionChanged="RAMListBox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <Run Text="{Binding CounterName, Mode=OneWay}" />
                        <Run Text="{Binding InstanceName, Mode=OneWay}" />
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>                                         
        <Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1" Click="RAMSelectAllButton_Click" >
            <TextBlock Text="SELECT ALL"/>
        </Button>
        <Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" Click="RAMUnSelectAllButton_Click" >
            <TextBlock Text="UNSELECT ALL"/>
        </Button>
    </Grid>
</TabItem>

Это то, что я сделал, и, как вы, возможно, уже знаете, это не работает. Приведенный выше код предназначен только для одной записи в моем словаре, где ключ - «Память».

В моем коде я установил DataContext:

this.DataContext = appData.Counters;

AppData.Counters - это тот словарь, который я представил в начале.

Вот чего я хотел бы добиться: независимо от того, сколько записей в моем словаре, мой TabControl будет отображать TabItem для каждой из них. Каждый TabItem имеет ListBox и 2 кнопки. Мне тоже нужно иметь доступ к ним (чтобы очистить список и иметь событие щелчка для каждой кнопки).

Я действительно не знаю, как это сделать, надеюсь, ты сможешь мне помочь.

0
Loreno 8 Сен 2016 в 09:18

2 ответа

Лучший ответ

Привязка TabControl к элементам в словаре:

<Window.Resources>

    <DataTemplate x:Key="templateForTheContent" >
        <StackPanel>
            <ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" 
                     ItemsSource="{Binding Value, Mode=OneWay}"
                     SelectionMode="Multiple"
                         BorderThickness="1" BorderBrush="#FF8B8B8B">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock>
                                    <Run Text="{Binding CounterName, Mode=OneWay}" />
                                    <Run Text="{Binding InstanceName, Mode=OneWay}" />
                        </TextBlock>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="templateForTheHeader" >
        <TextBlock Text="{Binding Key}"/>
    </DataTemplate>

</Window.Resources>
<Grid>
    <TabControl TabStripPlacement="Left"  VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"
        ItemsSource="{Binding Counters}"
        ContentTemplate="{StaticResource templateForTheContent}"
        ItemTemplate="{StaticResource templateForTheHeader}">
    </TabControl>
</Grid>

Теперь словарь нельзя наблюдать, поэтому, если элементы будут добавляться / удаляться во время выполнения, вы можете рассмотреть возможность использования чего-то вроде ObservableDictionary вместо этого

1
Arie 8 Сен 2016 в 07:16

Как я сказал в одном из комментариев выше, я изменил свой Словарь на это:

//list of all counters
        public ObservableCollection<ObservableCollection<PerformanceCounter>> Counters
        {
            get { return _Counters; }
        }
        ObservableCollection<ObservableCollection<PerformanceCounter>> _Counters = new ObservableCollection<ObservableCollection<PerformanceCounter>>();    

Я использовал решение @Arie для написания этого XAML:

            <DataTemplate x:Key="templateForTheContent" >
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*"/>
                    <RowDefinition  Height="Auto"/>
                </Grid.RowDefinitions>
                <ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" 
                         ItemsSource="{Binding}"
                         SelectionMode="Multiple"
                             BorderThickness="1" BorderBrush="#FF8B8B8B">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock>
                                        <Run Text="{Binding CounterName, Mode=OneWay}" />
                                        <Run Text="{Binding InstanceName, Mode=OneWay}" />
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1"  >
                    <TextBlock Text="SELECT ALL"/>
                </Button>
                <Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" >
                    <TextBlock Text="UNSELECT ALL"/>
                </Button>
            </Grid>
        </DataTemplate>

            <DataTemplate x:Key="templateForTheHeader" >
                <TextBlock Text="{Binding CategoryName}"/>
            </DataTemplate>

        </Window.Resources>

Он правильно отображает столько вкладок, сколько я добавляю в свой класс ObservableCollection в коде позади.

Теперь у меня новая проблема: я не знаю, как получить доступ к каждому listBox из каждой вкладки. мне нужно иметь возможность читать список выбранных объектов.

0
Loreno 9 Сен 2016 в 06:24