我正在创建一个文本编辑器类型应用程序。我可以通过标签打开多个编辑器。在我的第一次尝试中,我使用简单的TextBox
es来编辑文本。一切正常。然后我创建了一个UserControl
封装文本框+按钮来执行文本操作,例如。粗体/斜体等我发现当我打开不同的标签时,它们都包含相同的内容。例如。在Tab1中,输入将出现在所有选项卡中的“hello world”。即使它们位于不同的标签中,也存在“无分离”
<Window.Resources>
<DataTemplate DataType="{x:Type vm:EditorTabViewModel}">
<me:MarkdownEditor />
</DataTemplate>
</Window.Resources>
然后我作为测试,尝试了一个文本框和用户控件,看看我是否有同样的问题。
<Window.Resources>
<DataTemplate DataType="{x:Type vm:EditorTabViewModel}">
<StackPanel>
<me:MarkdownEditor Text="{Binding Content}" Height="360" />
<TextBox Text="{Binding Content}" Height="360" />
</StackPanel>
</DataTemplate>
</Window.Resources>
然后我发现了一些奇怪的东西。使用新文档,内容应该没有任何内容,我的MarkdownEditor
在其文本框中有“System.Windows.Controls.Grid”,因为Grid绑定到文本。文本简单TextBox
按预期工作。此外,我在应用中具有相同内容的所有UserControl
仍存在同样的问题。
UserControl
<UserControl x:Class="MarkdownEditMVVM.Controls.MarkdownEditor.MarkdownEditor" ...>
<Grid>
<ToolBar Grid.Row="0">
<Button Command="{x:Static local:Commands.PreviewCommand}">
<Image Source="../../Images/16/zoom.png" />
</Button>
<!-- more buttons -->
</ToolBar>
<TextBox Grid.Row="1" x:Name="txtEditor" AcceptsReturn="True" Text="{Binding Path=Text, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</UserControl>
我发现这与我在标签绑定到ObservableCollection<TabViewModel>
假设我有 TabViewModel
,即使只是一个空类
public class TabViewModel {}
然后在我的窗口
中public partial class Window1 : Window
{
protected ObservableCollection<TabViewModel> _tabs;
protected ICollectionView _tabsCollectionView;
public Window1()
{
InitializeComponent();
this.DataContext = this;
_tabs = new ObservableCollection<TabViewModel>();
_tabs.Add(new TabViewModel());
_tabs.Add(new TabViewModel());
_tabsCollectionView = CollectionViewSource.GetDefaultView(_tabs);
}
public ICollectionView Tabs
{
get { return _tabsCollectionView; }
}
}
XAML
<TabControl ItemsSource="{Binding Tabs}" IsSynchronizedWithCurrentItem="True">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
我创建了一个托管@ mediafire的简单Visual Studio项目,说明了这个问题。我觉得它与TabViewModel
或标签数据模板
我通过添加另一个标签控件进一步测试了用户控件问题,这次没有TabViewModel
<TabControl Grid.Column="1">
<TabItem Header="Tab 1">
<TextBox />
</TabItem>
<TabItem Header="Tab 2">
<TextBox />
</TabItem>
</TabControl>
一切正常。更新也发布到mediafire
又做了一个发现。这一次,我测试了绑定。事情很好......
<TabControl Grid.Column="2" ItemsSource="{Binding Tabs}" IsSynchronizedWithCurrentItem="True">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TabTitle}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Text}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
更新也发布了@ mediafire
好的,我现在做了一套更完整的测试
TextBox
,标签绑定到ObservableCollection<TabViewModel>
。没有TextBox
的绑定。观察到的问题ObservableCollection<TabViewModel>
的选项卡。没有绑定TextBox
。没问题ObservableCollection<TabViewModel>
。没有TextBox
的绑定。没问题UserControl
,标签绑定到ObservableCollection<TabViewModel>
。没有UserControl
的绑定。观察到的问题UserControl
,标签绑定到ObservableCollection<TabViewModel>
。 UserControl
的绑定。观察到问题。文本绑定无法正常工作更新@ mediafire
答案 0 :(得分:3)
大编辑以响应更新
我可以通过以下步骤让您的mediafire示例正常工作:
Text
- 您不需要它将ContentTemplate
上的TabControl
更改为以下内容。这会导致UserControl.DataContext
属性设置为标签项DataContext
<DataTemplate>
<local:UserControl1 />
</DataTemplate>
将您的UserControl
更改为以下内容。这会将Text
属性绑定到UserControl.DataContext.Text
属性。
<TextBox Text="{Binding Text}" />
从this.DataContext = this
的构造函数中删除行UserControl1
- 这显然会替换用户控件的DataContext
。
这导致标签与您上传的示例应用中的预期值正确绑定
原始答案
您可以拥有UserControl
的多个实例 - 这不是您的问题。
您看到“System.Windows.Controls.Grid”文本的原因是因为在UserControl
中您将Text
属性绑定到this.DataContext.Text
而不是this.Text
} - of 你的UserControl
。
我认为您要做的是将用户控件中的TextBox
绑定更改为:
<TextBox Grid.Row="1" x:Name="txtEditor" AcceptsReturn="True"
Text="{Binding Path=Text,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type me:MarkDownEditor}}}" />
注意:这取决于me
命名空间设置为指向MarkDownEditor
所在的位置
答案 1 :(得分:0)
您可能对 WPF Application Framework (WAF) 的 Writer 示例应用感兴趣。它展示了如何通过应用MVVM模式来实现具有多个选项卡支持的文本处理应用程序。