2 быстрых WPF (Windows Presentation Foundation) вопроса о вкладках и комбинированных окнах - PullRequest
1 голос
/ 19 февраля 2010

Я очень начинающий программист WPF, поэтому мне нужна помощь в некоторых простых задачах.

1 - Как показано на рисунке, мне нужна вкладка (+) (это вкладка, созданная с помощью TabItem на данный момент, или это должна быть кнопка или что-то еще?: - /), чтобы создать вкладку слева от нее, скажем ( A1), повторное нажатие должно создать (A2), как в браузерах с вкладками ......... И, если возможно, нажатие (-) удаляет выбранную вкладку в приглашении пользователя.

альтернативный текст http://img191.imageshack.us/img191/4532/tabn.png

2 - Я хочу, чтобы пользователь вводил текст в текстовое поле с содержимым, разделенным запятой или точкой с запятой, и чтобы этот контент добавлялся в COMBOBOX при нажатии / нажатии кнопки, я полагаю, для этого требуется какая-то привязка данных? Не уверен, .. Так, что в конце его содержимое из текстового поля становится списком в ComboBox (при нажатии кнопки) .................... И, если возможно, текст, выбранный в текстовом поле, по нажатию кнопки (та же или другая кнопка, которая была выбрана для добавления содержимого текстового поля в комбинированный список), удаляет его из текстового поля и комбинированного списка.

Пожалуйста, помогите, я изучаю WPF, но мне нужна эта срочная помощь, которую я не могу решить с помощью моих текущих знаний об этом. Спасибо.

Ответы [ 2 ]

2 голосов
/ 20 февраля 2010

С привязкой данных и MVVM все проще. Поначалу сложнее, но в конечном итоге намного проще.

Создайте два класса, Item и ItemCollection, которые оба реализуют INotifyPropertyChanged. Item должен предоставлять свойство строки Text, а ItemCollection должно предоставлять свойство ObservableCollection<Item> Items и свойство Item SelectedItem.

Заставить конструктор класса ItemCollection заполнить Items тестовыми данными и задать SelectedItem.

Похоже, многое нужно сделать, прежде чем вы приступите к реализации элемента управления вкладками, но, поверьте мне, вам понравится результат. Ваш XAML для TabControl будет выглядеть примерно так:

<TabControl
    ItemsSource="{Binding Items}"
    SelectedItem="{Binding SelectedItem}">
    <TabControl.DataContext>
        <local:ItemsCollection/>
    </TabControl.DataContext>
    <TabControl.Resources>
        <DataTemplate DataType="{x:Type local:Item}">
            <TextBlock Background="AliceBlue" Text="{Binding Text}"/>
        </DataTemplate>
    </TabControl.Resources>
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <Style.Setters>
                <Setter Property="Header" Value="{Binding Text}"/>
            </Style.Setters>
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

Давайте разберемся, что это делает. Это создает TabControl. Он создает объект ItemsCollection и устанавливает его как TabControl DataContext. Вы связали ItemSource с Items, поэтому TabControl создаст TabItem для каждого элемента. Он будет применять ItemContainerStyle к каждому TabItem, который устанавливает свое свойство Header в свойство Item Text.

Когда элемент управления отображает содержимое вкладки, он находит элемент, который он отображает, просматривает ресурсы, чтобы найти DataTemplate, чей DataType соответствует элементу, и использует этот шаблон. Поскольку мы определили его в TabControl.Resources, вы получите красивый синий фон и свойство Text снова.

Это, похоже, многое пережить. Но теперь вам не нужно писать код, который манипулирует пользовательским интерфейсом; вы просто пишете код, который манипулирует вашим ItemsCollection, и пользовательский интерфейс в значительной степени заботится о себе.

Теперь давайте позаботимся о добавлении новых вкладок. Что мы собираемся сделать, это добавить новый элемент в элемент управления, который, когда он становится выбранным, добавляет новый элемент в коллекцию Items.

Создайте новый класс с именем, о, ControlItem. Имейте это из Item. Измените конструктор ItemsCollection, чтобы последний добавленный элемент был ControlItem, а не Item. И установите для свойства Text этого элемента значение «+».

Добавьте этот метод к ItemsCollection:

public Item AddItem()
{
    Item newItem = new Item {Text = "New item"};
    Items.Insert(Items.Count-1, newItem);
    return newItem;
}

Теперь добавьте код своего окна в качестве обработчика событий SelectionChanged для вашего TabControl:

void TabControl_SelectionChanged(object sender, RoutedEventArgs e)
{
    TabControl tc = (TabControl) sender;
    if (tc.SelectedItem is ControlItem)
    {
        ItemsCollection ic = (ItemsCollection) tc.DataContext;
        tc.SelectedItem = ic.AddItem();
    }
}

Вы можете реализовать аналогичную логику для удаления элемента из списка, но вам нужно будет ввести другую переменную в ItemsCollection для отслеживания ранее выбранного элемента, чтобы вы могли знать, какой элемент удалить.

Еще одна вещь, которую вы можете сделать: реализовать свойство Background в Item и добавить установщик в ItemContainerStyle, который связывает свойство TabItem Background с ним. Затем вы можете перегрузить это свойство в ControlItem, чтобы ваши вкладки добавления и удаления выглядели по-разному.

Вы также можете реализовать различные подклассы для своих элементов управления, и они будут предоставлять метод, который вы вызываете в обработчике события SelectionChanged. Таким образом, обработчик событий не должен ничего знать о том, что делает элемент управления, по которому щелкают. На самом деле, если вы сделаете метод частью Item и у вас ничего не будет делать, если он не переопределен, окну даже не нужно знать, что Item имеет подклассов.

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

0 голосов
/ 19 февраля 2010

Управление вкладкой должно быть простым.Обработайте событие Click на вкладке +, создайте новую вкладку и сделайте ее активной вкладкой.Должно быть легко ... Я должен бежать, поэтому не могу показать вам код ответа прямо сейчас.Попробуйте и вернитесь с любыми проблемами.

В следующей части я могу быть немного более полезным

<StackPanel>
            <TextBox x:Name="txtOptions" TextChanged="OnTextChanged"></TextBox>
            <ComboBox x:Name="cboSelect" ItemsSource="{Binding Path=Options}"/>
        </StackPanel>

в окне с выделенным кодом (или в вашем классе) необходимо реализовать INotifyPropertyChanged,Также установите свойство DataContext окна для себя (например, в ctor), например this.DataContext = this;

public partial class Window1 : Window, INotifyPropertyChanged
   {
       string[] _options;
       public string[] Options
       {
           get
           {  return _options;         }
           set
           {
               _options = value;
               if (this.PropertyChanged != null)
                   this.PropertyChanged(this, new PropertyChangedEventArgs("Options"));
           }
       }

Обработчик события с измененным текстом изменяет свойство Options в выделенном коде и запускает уведомление о том, что свойствобыл изменен.Combobox получает уведомление, так как он привязан к данным и автоматически обновляется.

private void OnTextChanged(object sender, TextChangedEventArgs e)
      {
          this.Options = txtOptions.Text.Split(';');
      }
...