【问题标题】:Having a usercontrol that change to be edited?有一个要编辑的用户控件?
【发布时间】:2015-07-13 20:02:27
【问题描述】:

我之前在 WPF 中编写了几个应用程序,但我不确定我应该如何做这个:

我正在尝试制作一个“通用应用程序”,针对带有 win10 Iot 的树莓派上的小屏幕设计。

我想创建一个用户控件,它显示一个值,当单击它时会展开以占据全屏,允许我使用一些额外的按钮很好地编辑它(显示在用户控件的扩展版本中)(例如,数字递增/递减,+ 确定/取消按钮)。当我点击这个展开的用户控件中的 Ok 按钮时,它应该将 EditedValue 复制到 realValue (vars)。

我对如何使用不同的显示器(不同的布局、不同的组件、占据窗口的所有位置)来完成这个部分有点困惑,并且希望得到一些帮助。

【问题讨论】:

  • 我想做类似的事情。你有什么想法吗?我个人会制作一个单独的编辑页面。
  • @AlexH 我通常会这样做,但由于它是一个非常通用的编辑值,我想在几个地方都有它
  • 带有后退按钮的页面仍然可以解决问题。有什么理由不使用吗?
  • 如果您需要任何帮助,您需要编辑您的问题。你试过什么,什么不起作用,什么代码你不明白?这应该是一个相当简单的解决方案。谷歌应该有你需要的一切。
  • 通过阅读教程开始学习。尝试一些东西然后回来,只是获得显示值或工作的基本功能。如果他们有工作要做,他们会更容易提供帮助。没有人会为你做这一切。阅读 MVVM 并开始正确设计您的应用程序。

标签: c# wpf win-universal-app iot


【解决方案1】:

@Jordy van Eijk 为您提供了一个可行的解决方案,但由于您要求提供示例,我将为您提供我自己的实现。请注意,您可以通过多种变体和其他方式执行此操作,并且由于您的问题似乎很广泛,我只会填写初始设计。

我的方法使用 MVVM 设计模式: 内容展示器将绑定到视图模型并显示当前数据模板。数据模板将视图模型与用户控件相关联。用户控件包含您的视图、调整所选项目大小的绑定以及显示/隐藏扩展显示的触发器。

内容展示器 (MainWindow.xaml):

<ContentPresenter Content="{Binding CurrentView}"/>

数据模板 (MainWindow.xaml):

<Window.Resources>
    <DataTemplate DataType="{x:Type viewModel:UserControl1ViewModel}" >
        <view:UserControl1/>
    </DataTemplate>
</Window.Resources>

用户控件(UserControl1.xaml):

<UserControl.Resources>
    <Style x:Key="ExtendedControl" TargetType="Button">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsVisible}" Value="True">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<Grid HorizontalAlignment="Left" Background="Blue" Width="525">
    <Button Content="Resize Control" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding Width}" Height="265" Command="{Binding ResizeCommand}" Margin="10,30,0,0"/>
    <Button Content="Extended Control" Style="{StaticResource ExtendedControl}" Margin="383,32,25,258"/>
</Grid>

用户控件 1 视图模型 (UserControl1ViewModel.cs):

    public class UserControl1ViewModel : ViewModelBase
{
    public ICommand ResizeCommand
    {
        get
        {
            if (_resizeCommand == null) _resizeCommand = new RelayCommand(ResizeButton, () => true);
            return _resizeCommand;
        }
    }

    public bool IsVisible
    {
        get { return _isVisible; }
        set
        {
            _isVisible = value;
            RaisePropertyChanged("IsVisible");
        }
    }

    public double Width
    {
        get { return _width; }
        set
        {
            _width = value;
            RaisePropertyChanged("Width");
        }
    }

    private RelayCommand _resizeCommand;

    private bool _isVisible;

    private double _width;

    public UserControl1ViewModel()
    {
        Width = 100.0;
        IsVisible = false;
    }

    private void ResizeButton()
    {
        Width = Application.Current.MainWindow.ActualWidth * .65;
        IsVisible = true;
    }
}

点击前:

点击后:

这概述了创建您指定的基础应用程序所需的主要部分。当按下 resize 控件时,其宽度绑定更改为将其大小扩展为应用程序主窗口的 65%,并且扩展控件按钮的可见性绑定更改为 true。 Id 包括调整大小的图片,但我的声誉还不允许。我希望您像其他人所建议的那样将 MVVM 视为一种未来的架构模式,如果您在我的简单概述之外还有任何其他问题,请随时与我联系。祝你好运!

编辑:基本视图模型、命令和绑定属性的类来自 MVVM Light 库。您可以使用以下方法从 Visual Studio 将其导入您的项目:工具 -> NuGet 包管理器 -> 管理解决方案的 NuGet 包 -> 搜索“MVVM Light”

编辑 2

有关您的评论的示例。我们有一个父网格,其中包含一个始终为最大窗口大小的 70% 的编辑器视图和一个用于扩展控制面板大小的绑定:

查看:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="7*"/>
        <ColumnDefinition Width="{Binding Width}"/>
    </Grid.ColumnDefinitions>

    <ContentPresenter Content="{Binding ViewManager.EditorControlView}" Grid.Column="0"/>
    <ContentPresenter Content="{Binding ViewManager.ExtendedControlView}" Grid.Column="1"/>
</Grid>

绑定:

public string Width
{
    get { return _width; }

    set
    {
        _width = value;
        RaisePropertyChanged("Width")
    }
}

//set our extended control to the other 30 percent of the window size
Width = "3*";

要根据 MVVM 标准正确更改此宽度,我们需要在我们的视图模型之间使用某种形式的通信,幸运的是,这是您可以从这里学到的另一课。仅仅因为 iv 在整个示例中都使用了 MVVM Light,id 建议在 google 中搜索“MVVM Light Messenger”,因为它提供了一种可靠的通信方式。使用它,您可以提高更改宽度以从应用程序的任何位置隐藏父视图中的其他窗口组件。 :D

【讨论】:

  • 好吧,我明白了,我关心的是:如果所有者的父级是带有其他组件的网格怎么办?我不确定为什么仅仅因为我们设置了它的宽度,它就会占据整个父级位置
  • @J4N 刚刚添加了一个编辑二,您可以查看它解释了我相信您所描述的内容。
  • 是的,我明白了,但目标是此用户控件的父级不必知道其子级(用户控件)的行为。
  • @J4N 如果您的父级有网格,则子级无法在不知道其父级的情况下正确共享窗口。使用消息传递,这是一个松散耦合的系统,父母不会依赖孩子,而是在不使用时免费为其提供调整大小的能力。
  • @J4N 所以我最初的设计是让用户控件完成所有隐藏和包含扩展视图的工作,而编辑两个将它们分隔在两个不同的用户控件中,依赖于某些系统(如消息传递)进行交互。这应该为您提供一个简单的基础来提出您需要的任何最终设计,因为两者都是通用的并且可以混合使用。
【解决方案2】:

为什么不创建一个带有控件模板的用户控件,该控件模板将根据其模板的某些属性进行更改。带触发器的 ControlTemplate

【讨论】:

  • 好的,但我怎样才能让它使用用户控件中的所有可用空间
  • 通过将控件停靠在用户控件内并将用户控件停靠在其父控件内等等等等?
【解决方案3】:

您正在寻找的是 Accordian Control。这些很容易实现,但可能需要一些工作才能使外观/动画效果很好。 HERE 是一个带有示例和文档的开源项目。 This duplicate question(我的意思是你的是重复的,另一个在前)也提供了多种解决方案。

解决您问题的第二个组成部分 - 如何适应小屏幕 - 有几个很好的设计指南。你可以看看Apple Watch Human Interface Guidelines(那肯定是小屏幕),或者你可以在UX/UI Stack Exchange.寻求建议

【讨论】:

  • 感谢您的回答。我不确定您的答案是否是我正在寻找的,因为在这里您只有一个允许专注于某些项目的容器,在我的情况下,该容器可能是应该完全隐藏的 Grid/Dock 一个元素
  • 这是手风琴视图的定义。在你点击它之前它是完全隐藏的,然后它会打开以显示里面的东西。尝试查看链接,或者只是谷歌手风琴视图。
  • 我做到了,但我看到的是,这个“手风琴”容器总是有一个初始位置,它没有完全使用,并且可能在某个时候完全使用它。就我而言,我想要一个用户控件,它只使用 30% 的空间,然后使用全部空间。目标是在任何视图中都有一个 UserControl 以具有此行为,而不是视图必须每次都知道此行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2013-05-10
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多