c# – 如何将ViewModel中的信息转换为在View中显示

c# – 如何将ViewModel中的信息转换为在View中显示,第1张

概述我正在处理一个显然简单的问题,即使用 WPF和MVVM显示油箱中的液位. 为了显示坦克,我使用了一个带有矩形的DockPanel.矩形的高度根据罐中的液体量而变化.在坦克的顶部,我有一个TextBlock,显示坦克中存在的液体量. 我在XAML中定义了这个: <DockPanel x:Name="tankView" HorizontalAlignment="Left" Height="212" V 我正在处理一个显然简单的问题,即使用 WPF和MVVM显示油箱中的液位.

为了显示坦克,我使用了一个带有矩形的DockPanel.矩形的高度根据罐中的液体量而变化.在坦克的顶部,我有一个TextBlock,显示坦克中存在的液体量.
我在XAML中定义了这个:

<DockPanel x:name="tankVIEw" HorizontalAlignment="left" Height="212" VerticalAlignment="top" WIDth="144" DataContext="{Binding Source={StaticResource Tankviewmodel}}">            <TextBlock x:name="oilQuantity" HorizontalAlignment="Right" VerticalAlignment="top" DockPanel.Dock="top" margin="0,10,0" Text = "{Binding TxtOilQuantity,Mode=OneWay}"/>            <Rectangle x:name="oilLevel" Fill="Green" Height="66" stroke="Black" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" DockPanel.Dock="Bottom"/></DockPanel>

您还可以看到我已经创建了一个遵循MVVM模式的Tankviewmodel类和一个TankModel类.

显示TextBlock中的液体数量很简单,数据绑定可以完美地完成工作.但是,当涉及到矩形的高度时,会出现一些问题,因为我无法找到正确分离VIEw和viewmodel之间关注点的方法.

矩形的高度取决于最大容量和罐中液体的数量,这样我就可以得到一个数字,告诉我罐的填充百分比,如下:

public class Tankviewmodel : INotifyPropertyChanged{    private TankModel tankModel = new TankModel(2500);    public int IntFilledPercentage {        get {            if (tankModel.OilQuantity == 0)                return 0;            else                return Convert.ToInt32(((double)tankModel.OilQuantity / tankModel.capacity) * 100);        }    }    public event PropertyChangedEventHandler PropertyChanged;    protected voID NotifyPropertyChanged(String info) {        if (PropertyChanged != null) {            PropertyChanged(this,new PropertyChangedEventArgs(info));        }    }}

但是,我不能将此属性直接绑定到矩形的高度,并为这样的属性赋值,听起来像VIEw应该负责的东西.
为了实现这一点,我必须在视图中插入一些代码,将这个百分比值转换为矩形的高度.

我可以通过实现VIEw的OnPropertyChanged()回调来实现这一目的吗?

您对如何简化我已经实施的架构有任何建议吗?

解决方法 补充罗里.当您不需要固定的Converter参数但使用某个容器的实际高度时,也可以使用MultiBinding和IMultiValueConverter.

这允许使用父母的实际高度来设定液体的高度.

在我的例子中,我使用带边框的网格来代表gui上的液体罐.

视图模型:

public class MainWindowviewmodel : PropertyChangedBase // from Calburn.Micro (see nuget){    private int _liquIDPerc;    public MainWindowviewmodel()    {        liquIDPercentage = 25;    }    public int liquIDPercentage    {        get { return _liquIDPerc; }        set        {            if (value == _liquIDPerc) return;            _liquIDPerc= value;            NotifyOfPropertyChange(() => liquIDPercentage);        }    }}

转换器:

/// <summary>/// Converter which expects two params. percentage and maximum height/// </summary>public class liquIDLevelConverter : IMultiValueConverter{    public object Convert(object[] values,Type targettype,object parameter,CultureInfo culture)    {        var percentage = (int) values[0];        var maxHeight = (double) values[1];        return percentage*maxHeight*0.01;    }    public object[] ConvertBack(object value,Type[] targettypes,CultureInfo culture)    {        throw new NotImplementedException();    }}

XAML:

<Window x:Class="UiliquedTankDemo.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:d="http://schemas.microsoft.com/Expression/blend/2008"        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"        xmlns:local="clr-namespace:UiliquedTankDemo"        xmlns:system="clr-namespace:System;assembly=mscorlib"        mc:Ignorable="d"        title="MainWindow" Height="350" WIDth="525">    <Window.Resources>        <local:MainWindowviewmodel x:Key="viewmodel" />        <local:liquIDLevelConverter x:Key="liquIDLevelConverter" />    </Window.Resources>    <DockPanel DataContext="{StaticResource viewmodel}">        <!-- move the slIDer to move the level of the liquID -->         <SlIDer Minimum="0" Maximum="100" Value="{Binding liquIDPercentage}"                 DockPanel.Dock="Bottom"                 margin="0"/>        <!-- liquID container representation using a grID -->         <GrID name="liquIDContainer" margin="200,5">            <GrID.RowDeFinitions>                <RowDeFinition Height="*"/>                <RowDeFinition Height="auto"/>            </GrID.RowDeFinitions>            <border GrID.Row="1" Background="Blue" margin="0">                <border.Height>                    <MultiBinding Converter="{StaticResource liquIDLevelConverter}">                        <Binding Path="liquIDPercentage"></Binding>                        <Binding Path="ActualHeight" relativeSource="{relativeSource Mode=FindAncestor,AncestorType={x:Type GrID}}"></Binding>                    </MultiBinding>                </border.Height>            </border>            <border GrID.Row="0" GrID.rowspan="2"  borderBrush="Black" borderThickness="1" />        </GrID>    </DockPanel></Window>
总结

以上是内存溢出为你收集整理的c# – 如何将ViewModel中的信息转换为在View中显示全部内容,希望文章能够帮你解决c# – 如何将ViewModel中的信息转换为在View中显示所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1220147.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存