WPF 布局和特定的“数据绑定”

发布于 2024-12-11 21:16:42 字数 495 浏览 0 评论 0原文

我正在编写一个 WPF 95% GUI 应用程序,并且需要特定的快捷方式图标行为。 一张图像有时比(很多)文字更好,所以这是基本布局: (作为新用户,无法附加图像...)

http://imageshack。 us/f/705/appb.jpg/

- 底部子菜单中的每个图标代表应用程序中的一个控制“页面” - 固定图标。 - 左侧的图标是快捷方式 - 最近的和收藏的 - 根据底部图标的点击。 -我使用堆栈面板作为容器,并且项目数量是固定的。 - 每个控件集都有它自己的上下文菜单。

我想要完成的任务如下: 当用户单击底部菜单中的某个项目时,我希望它“神奇地出现”在“最近”面板中。当用户在“最近”面板上单击“删除”(上下文菜单)时,我需要(右键单击)图标消失。

现在我的(工作)解决方案非常麻烦,我确信存在一个优雅的解决方案。

非常感谢任何建议, 丹尼尔.

I'm writing a WPF 95% GUI application, and need a specific shortcut-icon behaviour.
One image is sometimes better than (lots of) words, so here's the basic layout:
(as a new user, couldn't attach an image...)

http://imageshack.us/f/705/appb.jpg/

-Every icons in the bottom sub menu represents a control "page" in the app - FIXED icons.
-The icons on the left are shortcuts - recent and favourites - according to clicks on the bottom icons.
-I'm using stack-panels as containers, and the number of items is fixed.
-every control set has it's own context-menu.

What I'm trying to accomplish is as follows:
When the user clicks an item in the bottom menu, I want it to "magically appear" in the "Recent" panel. When user clicks "remove" (context menu) at the "Recent" panel, I need the (right-clicked) icon to go away.

Right now my (working) solution is unbelievably cumbersome, and I'm sure an elegant one exists..

Would very much appreciate any advice,
Daniel.

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

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

发布评论

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

评论(1

几度春秋 2024-12-18 21:16:43

我假设您为此使用 MVVM 模式?如果没有,你应该是。

因此,假设您使用 MVVM,这样的操作对您有用:

class BottomPanelViewModel
{
    public BottomPanelViewModel()
    {
        Items = new ObservableCollection<PageViewModel>();
        ItemsView = new ListCollectionView(Items);
        ItemsView.CurrentChanged += SelectionChanged;
    }

    public ObservableCollection<PageViewModel> Items { get; private set; }
    public ListCollectionView ItemsView { get; private set; }

}    

class RecentPanelViewModel
{
    public RecentPanelViewModel()
    {
        Items = new ObservableCollection<PageViewModel>();
    }

    public ObservableCollection<PageViewModel> Items { get; private set; }
}

class WindowViewModel
{
    public WindowViewModel()
    {
        BottomPanel = new BottomPanelViewModel();
        RecentPanel = new RecentPanelViewModel();

        BottomPanel.CurrentChanged +=  (s, e) =>
        {
            RecentPanel.Items.Add(BottomPanel.ItemsView.CurrentItem);
        };
    }

    public BottomPanelViewModel BottomPanel { get; private set; }
    public RecentPanelViewModel RecentPanel { get; private set; }
}

在窗口构造函数中,创建一个 WindowViewModel 实例并将其用作 DataContext:

public Window()
{
    InitializeComponent();
    DataContext = new WindowViewModel();
}

然后在 XAML 中,您可以绑定到 WindowViewModel 的属性:

<Window ...>
    <DockPanel>
        <ListBox DockPanel.Dock="Bottom" 
                 ItemsSource="{Binding BottomPanel.ItemsView}"
                 IsSynchronizedWithCurrentItem="True"/>
        <ListBox DockPanel.Dock="Left" 
                 ItemsSource="{Binding RecentPanel.Items}"/>
    </DockPanel>
</Window>

说明: WindowViewModel 包含一个BottomPanelViewModel 和一个RecentPanelViewModel。每个都包含一个 ObservableCollection of Items,底部面板还公开一个集合视图。集合视图允许我们跟踪 UI 中的当前选择。

我在示例 XAML 中使用简单的 ListBox,但您可以使用您喜欢的任何 ItemsControl。

当底部面板中的选择发生变化时,窗口视图模型会听到此消息并将所选项目添加到最近面板的 ObservableCollection 中。显然,您需要在此处添加逻辑来检查重复项等。

I assume you're using the MVVM pattern for this? If not, you should be.

So, assuming you're using MVVM, would something like this work for you:

class BottomPanelViewModel
{
    public BottomPanelViewModel()
    {
        Items = new ObservableCollection<PageViewModel>();
        ItemsView = new ListCollectionView(Items);
        ItemsView.CurrentChanged += SelectionChanged;
    }

    public ObservableCollection<PageViewModel> Items { get; private set; }
    public ListCollectionView ItemsView { get; private set; }

}    

class RecentPanelViewModel
{
    public RecentPanelViewModel()
    {
        Items = new ObservableCollection<PageViewModel>();
    }

    public ObservableCollection<PageViewModel> Items { get; private set; }
}

class WindowViewModel
{
    public WindowViewModel()
    {
        BottomPanel = new BottomPanelViewModel();
        RecentPanel = new RecentPanelViewModel();

        BottomPanel.CurrentChanged +=  (s, e) =>
        {
            RecentPanel.Items.Add(BottomPanel.ItemsView.CurrentItem);
        };
    }

    public BottomPanelViewModel BottomPanel { get; private set; }
    public RecentPanelViewModel RecentPanel { get; private set; }
}

In your window constructor, create a WindowViewModel instance and use it as your DataContext:

public Window()
{
    InitializeComponent();
    DataContext = new WindowViewModel();
}

Then in your XAML you can bind to the properties of the WindowViewModel:

<Window ...>
    <DockPanel>
        <ListBox DockPanel.Dock="Bottom" 
                 ItemsSource="{Binding BottomPanel.ItemsView}"
                 IsSynchronizedWithCurrentItem="True"/>
        <ListBox DockPanel.Dock="Left" 
                 ItemsSource="{Binding RecentPanel.Items}"/>
    </DockPanel>
</Window>

Explanation: the WindowViewModel contains a BottomPanelViewModel and a RecentPanelViewModel. Each contain an ObservableCollection of Items, and the bottom panel also exposes a collection view. The collection view allows us to track the current selection in the UI.

I'm using simple ListBoxes in the example XAML, but you can use whatever ItemsControl you like.

When the selection changes in the bottom panel, the window view model hears this and adds the selected item to the recent panel's ObservableCollection. You'll obviously want to add logic here to check for duplicates etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文