我可以在1个应用相同的用户控件的多个实例? [英] Can I have multiple instances of the same UserControl in 1 app?
问题描述
我创建一个文本编辑器类型的应用程序。我可以有多个通过编辑选项卡中打开。在我第一次尝试,我用简单的文本框
ES编辑文本。一切工作正常。然后,我创建了一个用户控件
封装文本框+按钮来执行文本操作如。粗体/斜体等我发现,当我打开不同的标签,它们都包含相同的内容。例如。在TAB1我输入的Hello World将出现在所有选项卡。有不分离,即使它们在不同的标签页
I am creating a Text Editor Type app. I can have multiple editors open via tabs. In my first try, I used simple TextBox
es to edit text. Everything worked ok. Then I created a UserControl
encapsulating the text box + buttons to perform text manipulation eg. bold/italic etc. I found out that when I open different tabs, they all contain the same content. eg. In Tab1 i enter "hello world" that will appear in all tabs. There is "no separation" even though they are in different tabs
<Window.Resources>
<DataTemplate DataType="{x:Type vm:EditorTabViewModel}">
<me:MarkdownEditor />
</DataTemplate>
</Window.Resources>
然后我作为测试,尝试了文本框和用户控件一起看看我是否有同样的问题。
I then as a test, tried a textbox and the usercontrol together to see if I have the same problem.
<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,因为它网格被绑定到文本。文字简单的文本框
按预期工作。此外,我还不得不与所有用户控件
在具有相同内容的应用程序S中的同样的问题。
I then discovered a few strange things. With a new document, where content should be nothing, my MarkdownEditor
had "System.Windows.Controls.Grid" in its text box as it a Grid was bound to the text. Text simple TextBox
works as expected. Also I still had the same problem with all UserControl
s in the app having the same content.
用户控件X;为用户控件
The XAML for the 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>
I discovered that this has something to do with the way I have usercontrols rendered in the tabs where tabs are bound to ObservableCollection<TabViewModel>
假设我有一个 TabViewModel
哪怕只是一个空类
Suppose I have a TabViewModel
even just a empty class
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>
我创建托管一个简单的Visual Studio项目@的主人MediaFire 说明这个问题。我有一种感觉它得到的东西做的 TabViewModel
s或Tab键数据模板
I have created a simple Visual Studio Project hosted @mediafire illustrating this problem. I have a feeling it got something to do with the TabViewModel
s or the Tab Data Templates
我通过增加另一个标签控件进一步测试用户控制问题,这次没有 TabViewModel
I further tested the user control problem by adding another tab control, this time without the TabViewModel
<TabControl Grid.Column="1">
<TabItem Header="Tab 1">
<TextBox />
</TabItem>
<TabItem Header="Tab 2">
<TextBox />
</TabItem>
</TabControl>
这一切工作正常。更新还张贴到主人MediaFire
制造的又一发现。这一次,我有约束力的测试。事情的来龙去脉罚款...
Made yet another finding. This time, I tested with a binding. things worked fine ...
<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
好吧,现在我做了一个更完整的测试集
Ok now I did a more complete set of tests
- 行0,列0:
文本框
,标签绑定到的ObservableCollection< TabViewModel>
。不绑定文本框
。问题观察 - 行0,1列:文本框,正常的TabItems,标签未绑定到
的ObservableCollection< TabViewModel>
。没有绑定为文本框
。没有问题 - 行0,第2列:文本框,标签绑定到
的ObservableCollection< TabViewModel>
。不绑定文本框
。没有问题 - 第1行,列0:
用户控件
,标签绑定到的ObservableCollection< TabViewModel>
。不绑定用户控件
。问题观察 - 第1行,第2列:
用户控件
,标签绑定到的ObservableCollection< TabViewModel>
。为用户控件
绑定。问题观察。文本绑定不工作
- Row 0, Column 0:
TextBox
, Tabs bound toObservableCollection<TabViewModel>
. No Bindings forTextBox
. Problem observed - Row 0, Column 1: TextBox, Normal TabItems, Tabs not bound to
ObservableCollection<TabViewModel>
. No Binding forTextBox
. No problems - Row 0, Column 2: TextBox, Tabs bound to
ObservableCollection<TabViewModel>
. No Bindings forTextBox
. No Problems - Row 1, Column 0:
UserControl
, Tabs bound toObservableCollection<TabViewModel>
. No Bindings forUserControl
. Problem observed - Row 1, Column 2:
UserControl
, Tabs bound toObservableCollection<TabViewModel>
. Bindings forUserControl
. Problem observed. Text bindings not working
更新@的主人MediaFire
推荐答案
大修改响应更新
我能得到你的主人MediaFire例如通过采取以下步骤正常工作:
I can get your mediafire example to work correctly by taking the following steps:
- 删除依赖属性
文本
从用户控件 - 你不需要它 -
更改
的ContentTemplate
在的TabControl
的下方。这将导致UserControl.DataContext
属性设置为标签项目的DataContext
- Remove the dependency property
Text
from your user control - you don't need it Change your
ContentTemplate
on theTabControl
to the below. This causes theUserControl.DataContext
property to be set to the tab itemDataContext
<DataTemplate>
<local:UserControl1 />
</DataTemplate>
更改用户控件
来的下面。这种绑定文本
属性设置为 UserControl.DataContext.Text
属性。
Change your UserControl
to the below. This binds the Text
property to the UserControl.DataContext.Text
property.
<TextBox Text="{Binding Text}" />
删除行 this.DataContext =此
从构造的UserControl1
- 这显然会替换的DataContext
用户控件
Remove the line this.DataContext = this
from the constructor of UserControl1
- this will obviously replace the DataContext
for the user control.
这导致选项卡与您上传的示例应用程序的预期值被正确绑定
This caused the tabs to be correctly bound with the expected values in the sample app you uploaded
原来的答案
您可以有多个实例用户控件
- 这是不是在这里你的问题。
You can have multiple instances of a UserControl
- that isn't your problem here.
您所看到的System.Windows.Controls.Grid原因文字是因为在你的用户控件
你要绑定的文本
属性 this.DataContext。文字
而不是 this.Text
- 属性的 的你的用户控件$ C $的。C>
The reason you are seeing the "System.Windows.Controls.Grid" text is because in your UserControl
you are binding the Text
property to this.DataContext.Text
instead of this.Text
- the property of your UserControl
.
我想你想要做的是改变文本框
在用户控件绑定到:
I think what you want to do is change the TextBox
binding in your user control to:
<TextBox Grid.Row="1" x:Name="txtEditor" AcceptsReturn="True"
Text="{Binding Path=Text,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type me:MarkDownEditor}}}" />
注:这依赖于我
命名空间被设置为指向哪里你的 MarkDownEditor
位于
Note: this relies on the me
namespace being set up to point to wherever your MarkDownEditor
is located
这篇关于我可以在1个应用相同的用户控件的多个实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!