Dav*_*veS 4 .net c# wpf mvvm avalondock
我已经在这几周了...我正在创建一个在主窗口中使用Avalon Dock 2.0的WPF应用程序.我试图以MVVM的方式使用Docking Manager,所以我已经DockingManager.DocumentsSource绑定了ObservableCollection<object>我的一个属性MainViewModel.我还创建了一个自定义DataTemplateSelector并绑定它DockingManager.LayoutItemTemplateSelector.我遇到的问题:
ViewModel文件来源.DataTemplateSelector.SelectTemplate()被称为.SelectTemplate()是一个System.Windows.Controls.ContentPresenter而不是ViewModel我添加的对象.DataTemplate,它最终也会被绑定到ContentPresenter而不是ViewModel包含在内ContentPresenter.我设法在一个简单的WPF项目中复制问题,这是相关的代码:
主窗口:
<!-- MainWindow markup DataContext is bound to
I omitted the usual xmlns declarations -->
<Window
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:local="clr-namespace:AvalonTest"
Title="MainWindow">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<xcad:DockingManager DocumentsSource="{Binding Docs}">
<xcad:DockingManager.LayoutItemTemplateSelector>
<local:TestTemplateSelector>
<local:TestTemplateSelector.TheTemplate>
<DataTemplate>
<local:TestView/>
</DataTemplate>
</local:TestTemplateSelector.TheTemplate>
</local:TestTemplateSelector>
</xcad:DockingManager.LayoutItemTemplateSelector>
<xcad:LayoutRoot>
<xcad:LayoutPanel Orientation="Vertical">
<xcad:LayoutAnchorablePane/>
<xcad:LayoutDocumentPane/>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
MainViewModel:
class MainViewModel
{
//Bound to DockingManager.DocumentsSource
public ObservableCollection<object> Docs { get; private set; }
public MainViewModel()
{
Docs = new ObservableCollection<object>();
Docs.Add(new TestViewModel());
}
}
Run Code Online (Sandbox Code Playgroud)
DataTemplateSelector:
class TestTemplateSelector : DataTemplateSelector
{
public TestTemplateSelector() {}
public DataTemplate TheTemplate { get; set; }
//When this method is called, item is always a ContentPresenter
//ContentPresenter.Content will contain the ViewModel I add
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
//Just return the only template no matter what
return TheTemplate;
}
}
Run Code Online (Sandbox Code Playgroud)
TestView:
<!-- TestTemplateSelector will always return this TestView -->
<UserControl x:Class="AvalonTest.TestView"
xmlns:local="clr-namespace:AvalonTest">
<Grid>
<StackPanel Orientation="Vertical">
<TextBox Text="{Binding TestText}"/>
<Button Content="A Button"/>
</StackPanel>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
TestViewModel:
//TestView.DataContext should be set to this, but instead
//it gets set to a containing ContentPresenter
class TestViewModel : ObservableObject
{
private string testText = "TESTTESTTEST";
public string TestText
{
get { return testText; }
set
{
testText = value;
RaisePropertyChanged("TestText");
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
TestView没有正确绑定TestViewModel,因此"TESTTESTTEST"没有出现在TextBox.我已经检查了Avalon Dock的示例MVVM项目,他们DataTemplateSelector总是得到ViewModel而不是ContentPresenter.我究竟做错了什么?
在TestTemplateSelector上更改SelectTemplate的定义,如下所示:
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
//check if the item is an instance of TestViewModel
if (item is TestViewModel)
return TheTemplate;
//delegate the call to base class
return base.SelectTemplate(item, container);
}
Run Code Online (Sandbox Code Playgroud)
您应该始终检查传递的项是否是目标视图模型的实例,如果不是,则将调用委托给基类,以便WPF可以处理您不关心的对象.
| 归档时间: |
|
| 查看次数: |
1347 次 |
| 最近记录: |