棱镜标签=疼痛

发布于 2024-08-08 22:34:13 字数 1608 浏览 6 评论 0原文

我很难尝试使用 PRISM 2.0 for WPF 获得一个非常简单的场景。我希望我的应用程序的主工作区是一个 TabControl。每次添加视图时,我都希望它在 TabControl 上显示为 TabItem

听起来很容易吧?

我的区域位于我的 Shell.XAML 中,如下所示:

<Controls:TabControl 
    Name="MainRegion" 
    cal:RegionManager.RegionName="{x:Static Infrastructure:RegionNames.TabRegion}"
    ItemContainerStyle="{StaticResource ShellTabItemStyle}" />

样式:ShellTabItemStyle 如下所示:

<Style x:Key="ShellTabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Header" Value="{Binding Content.DataContext.HeaderInfo, RelativeSource={RelativeSource Self}}" />
</Style>

这应该设置 TabItemHeader > 到视图的 DataContext 上的 HeaderInfo 属性。 (我从这篇文章中得到这个想法)DataContext我的视图的 是一个非常简单的 Presenter ,上面有一个 HeaderInfo 属性:

public string HeaderInfo = "The Header Text";

我的视图是一个简单的 WPF 用户控件,看起来像这样:

  <StackPanel>
    <TextBox Text="Hello World" Name="MyTextBox"></TextBox>
    <Image Source="..SomeImage.PNG" Name="MyImage"></Image>
  </StackPanel>

到目前为止,所以好的。如果我将视图添加到该区域,我会得到一个选项卡控件,并且会得到一个文本设置为“标题文本”的选项卡。我的问题是选项卡上绝对没有内容出现。我的视图包含一个简单的 Image 和一个 TextBox,但它们都没有显示在 TabItem 中。如果我打开 Snoop 环顾四周,我会发现看不到任何图像。

我在这里缺少什么 - 有更简单的方法吗?

I am having difficulty trying to get a very simple scenario working with PRISM 2.0 for WPF. I want the main workarea of my application to be a TabControl. Each time I add a view, I want it to appear as a TabItem on the TabControl.

Sounds easy right?

My region, which is in my Shell.XAML looks like this:

<Controls:TabControl 
    Name="MainRegion" 
    cal:RegionManager.RegionName="{x:Static Infrastructure:RegionNames.TabRegion}"
    ItemContainerStyle="{StaticResource ShellTabItemStyle}" />

The style: ShellTabItemStyle looks like this:

<Style x:Key="ShellTabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Header" Value="{Binding Content.DataContext.HeaderInfo, RelativeSource={RelativeSource Self}}" />
</Style>

This should set the Header of the TabItem to the HeaderInfo property on the DataContext of the view. (I got this idea from this article) The DataContext of my view is a very simple Presenter which has a HeaderInfo property on it:

public string HeaderInfo = "The Header Text";

My view is a simple WPF usercontrol and looks like this:

  <StackPanel>
    <TextBox Text="Hello World" Name="MyTextBox"></TextBox>
    <Image Source="..SomeImage.PNG" Name="MyImage"></Image>
  </StackPanel>

So far, so good. If I add the view to the region I get a tab control and I get a tab with the text set to "The Header Text". My problem is that there is absolutely no content appearing on the tab. My view contains a simple Image and a TextBox, but neither of them show up in the TabItem. If I break out Snoop and look around, there isn't an image in sight.

What am I missing here - is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

澉约 2024-08-15 22:34:13

我无法得到任何建议的答案。广泛的谷歌搜索也没有帮助。我在周末思考了这个问题,并且思考得越多,我就越发现这种方法有一点代码味道。您将视图注入选项卡区域...发生了一些神奇的事情并添加了选项卡...您必须向存储在某个文件中的某些 XAML 样式添加一些难以理解的动态绑定,这可能会也可能不会设置您的标题文本。如果其中任何一个元素有一点点错误,您不会收到错误,但它不会工作。

在我看来,除非您对 PRISM、模型和 XAML 有深入的了解,否则这既脆弱(即非常容易损坏)又非常难以理解。幸运的是,有一种更好、更简单的方法可以做到这一点:

只需创建一个名为 TabRegionView 的视图,其中仅包含一个空白 TabControl。您可能想将其添加到 Shell.xaml 中。创建一个名为 InjectTabView 的事件,该事件具有 UserControl 类型的有效负载,并在 TabRegionView 控件中订阅此事件。当事件在 TabRegionView 中触发时,您手动创建 TabItem 并将视图添加到 TabItem,如下所示:

public void TabAdded(UserControl view)
{
    var item = new TabItem();
    item.Content = view;
    item.IsSelected = true;
    item.Header = "Header Text";
    mainTab.Items.Add(item);
}

当您想要将视图显示为新选项卡时,您的代码如下所示

    var view = new View(params);
    _eventAggregator.GetEvent<InjectTabViewEvent>()
        .Publish(view);

:由 TabRegionView 选取,并且该视图将作为新选项卡添加。您可以轻松地将视图包装在某种类型的线束中,其中包含标题文本、图像和布尔值以指示是否应自动选择选项卡。

恕我直言,这种技术具有双重优势,可以让您直接控制正在发生的事情,而且更容易遵循。

我非常有兴趣从 PRISM 官员那里得到对此的意见。

I was unable to get any of the suggested answers to work. Extensive googling didn't help either. I gave the problem some thought over the weekend and more I thought about it, the more it occured to me that there is a bit of a code smell about this approach. You inject a view into your Tab Region... some magic stuff happens and a tab gets added... you have to add some imcomprehensible dynamic binding to some XAML styling stored in a file somewhere and this may or may not set your header text. If any one single element of this is just a little bit wrong you won't get an error but it just won't work.

In my view this is both brittle (i.e. very easy to break) and pretty inpenetrable unless you have a deep understanding PRISM, the model, and of XAML. Fortunately there is a much nicer and simpler way to do this:

Simply create a view called TabRegionView which contains only a blank TabControl. You probably want to add this to your Shell.xaml. Create an Event called InjectTabView which has a Payload of type UserControl and subscribe to this event in your TabRegionView control. When the event fires in TabRegionView, you create the TabItem manually and add the view to the TabItem like so:

public void TabAdded(UserControl view)
{
    var item = new TabItem();
    item.Content = view;
    item.IsSelected = true;
    item.Header = "Header Text";
    mainTab.Items.Add(item);
}

When you want to display a view as a new tab, your code looks something like this:

    var view = new View(params);
    _eventAggregator.GetEvent<InjectTabViewEvent>()
        .Publish(view);

This will be picked up by TabRegionView and the view will be added as a new tab. You could easily wrap the View in harness of some type that contains header text, an image and bool to indicate whether or not the tab should be autoselected.

IMHO this technique has the dual advantages of giving you direct control of what is going on AND it is much easier to follow.

I'd be very interested to get an opinion on this from any PRISM officianados.

拿命拼未来 2024-08-15 22:34:13

如果您使用 RegionManager,则需要激活您的视图。可能有一些代码将视图添加到该区域,您只需要另外告诉该区域激活它。

public void AddViewToRegion(IRegion region, object view)
{
     region.Add(view);
     region.Activate(view);
}

这看起来很愚蠢,但如果你不这样做,你就会得到你所看到的行为。我发现这有点令人沮丧,但很容易解决。当您添加多个选项卡时,如果您至少不激活您添加的第一个视图,则行为会更加奇怪。

我的理解是,如果您不这样做,视图永远不会成为可视化树的一部分(这是当选项卡不在“中”时 TabControl 停用(从可视化树中删除)这一事实的副作用。这对于某些操作来说是有好处的,但会让这样的事情变得有点不稳定。

If you are using RegionManager, you need to Activate your view. There's likely some piece of code where you are adding the view to the region, you just additionally need to tell that region to activate it.

public void AddViewToRegion(IRegion region, object view)
{
     region.Add(view);
     region.Activate(view);
}

It seems silly, but you get the behavior you are seeing if you don't do this. I found this kinda frustrating, but it was easy enough to fix. The behavior is even stranger when you add multiple tabs if you don't at least Activate the first view you add.

My understanding is that if you don't do this, the view never becomes part of the visual tree (this is a side-effect of the fact that the TabControl deactivates (removes from the visual tree) when a tab isn't "in front". This is good for certain operations, but makes things like this be a little wonky.

傲鸠 2024-08-15 22:34:13

一些随机的想法:

  • 中删除样式
  • 尝试借助 Snoop 工具从 TabControl 检查视觉树 。您应该在 TabControl 下看到带有视图 UserControl 的 TabItem。接下来,您可以检查该 UserControl 及其子控件(您的视图的内容)有什么问题。它们可能由于某种原因被隐藏。
  • 其他需要考虑的事情 - RegionAdapter。 RegionAdapters 负责调整区域的视图以承载 UIControl。

Some random thoughts:

  • try to remove the style from TabControl
  • check visual tree with help of Snoop tool. You should see your TabItem with view's UserControl under the TabControl. Next you can check what's wrong with that UserControl and its children (your view's content). They are probably hidden for some reason.
  • other thing to think over - RegionAdapter. RegionAdapters are responsible for adapting regions' views to host UIControl.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文