Я использую WinUI 3 UWP TabView в своем приложении. Я знаю, что WinUI 3 все еще находится на этапе предварительного просмотра для UWP. Но все же я хочу знать обходной путь для моей проблемы, поскольку я хочу использовать TabView в своем приложении. Я просмотрел официальную документацию и образцы GitHub, но не смог найти решение. TabView НЕ отображает новую вкладку всякий раз, когда новый документ добавляется в коллекцию. Я много искал, но не мог найти решение. Пожалуйста, поделитесь решением/обходным путем. Вы можете предложить использовать WinUI 2, так как он стабилен для UWP. Но я уже пробовал это, и элементы управления WinUI 2 плохо сочетаются с существующими элементами управления UWP. Но WinUI 3 прекрасно сочетается. Все остальные элементы управления, кроме TabView, работают нормально. Когда я переключаюсь с DataBinding на ручное ведение списка TabItems, он работает отлично. Но мне не нужен шаблонный код. Я хочу добиться того же с помощью DataBinding. Я новичок в MVVM. Итак, если есть проблема с моей ViewModel, поделитесь обходным путем.
Это мой класс ViewModel:
using Microsoft.UI.Xaml.Controls;
using System.ComponentModel;
using System.IO;
using System.Text;
using MyApp.Utilities;
using System.Runtime.CompilerServices;
namespace MyApp.ViewModels
{
public class TextDocument : INotifyPropertyChanged
{
private int _documentId;
private string _fileName;
private string _filePath;
private string _textContent;
private Encoding _encoding;
private LineEnding _lineEnding;
private bool _isSaved;
public int DocumentId
{
get
{
return _documentId;
}
set
{
_documentId = value;
OnPropertyChanged(ref _documentId, value);
}
}
public string FileName
{
get
{
return _fileName;
}
set
{
OnPropertyChanged(ref _fileName, value);
}
}
public string FilePath
{
get
{
return _filePath;
}
set
{
OnPropertyChanged(ref _filePath, value);
FileName = Path.GetFileName(_filePath);
}
}
public string TextContent
{
get
{
return _textContent;
}
set
{
OnPropertyChanged(ref _textContent, value);
}
}
public Encoding FileEncoding
{
get
{
return _encoding;
}
set
{
OnPropertyChanged(ref _encoding, value);
}
}
public LineEnding LineEnding
{
get
{
return _lineEnding;
}
set
{
OnPropertyChanged(ref _lineEnding, value);
}
}
public string TabHeader
{
get
{
return string.IsNullOrEmpty(FileName) ? "Untitled Document" : FileName;
}
}
public bool IsSaved
{
get
{
return _isSaved;
}
set
{
OnPropertyChanged(ref _isSaved, value);
}
}
public bool IsInvalidFile
{
get
{
return (string.IsNullOrEmpty(FilePath) || string.IsNullOrEmpty(FileName));
}
}
public override bool Equals(object obj)
{
if (ReferenceEquals(obj, null))
return false;
if (ReferenceEquals(this, obj))
return true;
var comp = (TextDocument)obj;
return this.DocumentId == comp.DocumentId;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged<T>(ref T property, T value, [CallerMemberName] string propertyName = "")
{
property = value;
var handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
А это мой код XAML для TabView:
<TabView x:Name="MyTabView" AddTabButtonClick="TabView_AddTabButtonClick" TabCloseRequested="TabView_TabCloseRequested"
SelectionChanged="TabView_SelectionChanged"
Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Background="White"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
TabItemsChanged="TabView_TabItemsChanged"
SelectedIndex="0"
TabItemsSource="{x:Bind MyDocuments,Mode=OneWay}"
>
<TabView.TabItemTemplate>
<DataTemplate x:DataType="viewmodels:TextDocument">
<TabViewItem Header="{x:Bind TabHeader,Mode=OneWay}" IconSource="{x:Null}">
<TabViewItem.Content>
<TextBox x:Name="TextBoxInsideTab" Grid.Column="0" Grid.Row="0"
PlaceholderText="Drag and drop a file here or start typing"
Text="{x:Bind TextContent,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" FontSize="24"
UseSystemFocusVisuals="False"
BorderThickness="0"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
TextWrapping="Wrap"
IsSpellCheckEnabled="False"
CanBeScrollAnchor="True"
TextChanged="TextBox_TextChanged"
AcceptsReturn="True"
IsTabStop="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
/>
</TabViewItem.Content>
</TabViewItem>
</DataTemplate>
</TabView.TabItemTemplate>
</TabView>
А это мой код C#:
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using MyApp.ViewModels;
using Windows.Storage.Pickers;
using Windows.Storage;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MyApp
{
public sealed partial class MainPage : Page
{
private ObservableCollection<TextDocument> MyDocuments;
public MainPage()
{
this.InitializeComponent();
MyDocuments = new ObservableCollection<TextDocument>()
{
new TextDocument()
};
}
private void TabView_AddTabButtonClick(TabView sender, object args)
{
AddTabViewItemDefault(sender.TabItems.Count);
}
private void AddTabViewItemDefault(int index)
{
MyDocuments.Add(new TextDocument());
}
private void TabView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
MyDocuments.Remove(args.Item as TextDocument);
}
private void TabView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
}
}
}
Может быть, добавить UpdateSourceTrigger=PropertyChanged в TabItemsSource?
Отображается ли исходный TabItem?
@Chris Да, начальный TabItem отображается. Но если нажать кнопку AddTab, ничего не появится. Но элемент добавляется в ObservableCollection. И я попробовал Mode=TwoWay,UpdateSourceTrigger=PropertyChanged. Это тоже не работает.
@Chris Я думаю, что новые вкладки перекрывают старые. Потому что в ObservableCollection происходит изменение всякий раз, когда добавляется или удаляется новый элемент. Он не отображается в пользовательском интерфейсе. Можете ли вы собрать проект с кодом, который я отправил, и найти решение проблемы?
Вы видели мой ответ ниже? Ты это пробовал? Извините, я не смогу построить проект и т. д. Я на работе и занят другими делами...
Ваша ViewModel в порядке. Должно быть что-то с ObservableCollection, неправильно привязанным к TabControl. Может быть, добавить INotifyPropertyChanged в код класса и уведомить об изменении ObservableCollection после добавления элемента?
@ Крис Нет проблем. Спасибо за помощь. Я попробую ваше решение и свяжусь с вами.
Вы пробовали это: может быть, добавить INotifyPropertyChanged в код класса и уведомить об изменении ObservableCollection после добавления элемента?
@Chris Да, я попробовал. Тоже не получилось
@Chris ObservableCollection и TabView правильно работают с настольным приложением WinUI 3. Проблема существует только в библиотеке WinUI 3 UWP.