Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 隐藏元素与数据触发器_C#_Wpf_Xaml_Windows Runtime - Fatal编程技术网

C# 隐藏元素与数据触发器

C# 隐藏元素与数据触发器,c#,wpf,xaml,windows-runtime,C#,Wpf,Xaml,Windows Runtime,所以我刚刚加入了一个windows phone团队,他们倾向于按照以下思路做一些事情: <Image Width="74" Height="74" Source="ms-appx:///Assets/ImageCatagory/shoot icon.png" Visibility="{Binding SomeBoolParameter, Converter={StaticResource InvertedBoolToVisibilit

所以我刚刚加入了一个windows phone团队,他们倾向于按照以下思路做一些事情:

<Image Width="74"
       Height="74"
       Source="ms-appx:///Assets/ImageCatagory/shoot icon.png"
       Visibility="{Binding SomeBoolParameter,
       Converter={StaticResource InvertedBoolToVisibilityConverter}}" />
<Image Width="74"
       Height="74"
       Source="ms-appx:///Assets/ImageCatagory/shoot icon disabled.png"
       Visibility="{Binding SomeBoolParameter,
       Converter={StaticResource BoolToVisibilityConverter}}" />

我仔细看了一遍,心里想:代码重复,将2个元素加载到UI中,这(虽然很小)会加载不必要的内存-为什么在任何给定时间只需要一个图像时同时加载这两个图像

我把它改成这样:

<Image x:Name="HelperButtonIcon"
       Margin="19 0">

       <i:Interaction.Behaviors>

             <core:DataTriggerBehavior Binding="{Binding SomeBoolParameter}"
                                       ComparisonCondition="Equal"
                                       Value="True">

                   <core:ChangePropertyAction PropertyName="Source"
                                              TargetObject="{Binding ElementName=HelperButtonIcon}"
                                              Value="ms-appx:///Assets/ImageCatagory/helper icon on.png" />

             </core:DataTriggerBehavior>
             <core:DataTriggerBehavior Binding="{Binding SomeBoolParameter}"
                                       ComparisonCondition="Equal"
                                       Value="False">

                   <core:ChangePropertyAction PropertyName="Source"
                                              TargetObject="{Binding ElementName=HelperButtonIcon}"
                                              Value="ms-appx:///Assets/ImageCatagory/helper icon off.png" />

             </core:DataTriggerBehavior>

</i:Interaction.Behaviors>

通过使用DataTriggers,我在任何给定时间只使用1个元素,这对我来说似乎更有效。 然而,代码在相当小的事情上有点膨胀,此外,我担心关于图像加载和切换的性能问题。 我还没有找到关于这个问题的最佳实践的任何东西,尽管我很肯定它会更好,但我想确定一下。 因此,问题是:


使用数据触发器切换这些相同元素的属性是否比使用可见性开关更好?

我不会使用这两个选项,而是在视图模型中使用此登录:

public bool SomeBoolParameter
{
    get { /* ... */ }
    set
    {
        //...
        OnPropertyChanged("SomeBoolParameter");
        OnPropertyChanged("ImageUrl");
    }
}

public string ImageUrl
{
    get
    {
        return SomeBoolParameter ? "..." : "...";
    }
}


另外,如果您不做任何花哨的事情,为什么不使用内置的
DataTriggers
?我更喜欢
DataTrigger
选项如果我必须在您的两个选项中进行选择,它在逻辑上更干净。我不认为你应该过分担心记忆,除非它真的成为一个问题。

这个话题会引起很大争议。就我个人而言,我认为最初的实施更好。我的理由如下:

  • 现代RAMs能够储存数百万个缩略图
  • 如果您不断更改
    SomeBoolProperty
    值,您将从硬盘执行多次读取操作。磁盘IO相对较慢。此外,每次
    图像的源代码更改时,图像都会出现在RAM中,垃圾收集器需要更加努力地工作
  • 当其他人将来接管您的项目时,您会使其他人更难理解您的代码

  • 当然,如果场景中预加载了1000个图像,等待转换器告诉它们1000个图像中的哪一个应该可见,那么您的解决方案是完全合理的。

    WPF实际上进行了一些图像缓存。@H.B.但是如果缓存保存到硬盘上,它仍然与从原始源读取一样好。如果它在RAM上,那么它和原始解决方案一样好。我想首先重新编写该部分的主要原因是因为它是代码复制项目中的许多情况之一。显然,代码复制是一件非常糟糕的事情,在维护和开发过程中(应用程序尚未上线),它会使工作加倍。所以这只是一个小例子,我可以摆脱这样一件坏事。@Michaelthepatto然后另一种方法是对
    图像
    进行子类化,然后根据需要添加依赖属性来执行此行为。这样可以节省大量的代码重复。无论是谁,都很清楚这个想法是关于什么的。我发现你的建议的问题是,它让ViewModel控制UI。虚拟机被认为“不知道/不关心”他正在被呈现,因此持有图像的URL会违反MVVM模式的原则之一。@MichaelThePotato:视图模型是视图的模型;它应该描述视图数据,所以它保存像图像URL这样的数据是非常好的。图像URL与显示有关,与数据无关。UI本身应该使用VM的当前状态确定在任何给定时间显示哪个图像。处理这些事情不是虚拟机的工作。因此,对于VM来说,为UI显示图像URL之类的东西是不合适的。关于原始注释。windows phone中未实现DataTriggers。因此,基于行为的实现是唯一可用的实现。URL不必与数据、您的意见、应该进入VM的内容以及对我来说不应该显得太无根据的内容做任何事情。请注意,您还可以在样式中将默认值设为这些URL中的一个,并为第二个URL只设置一个datatrigger
    <Image Source="{Binging ImageUrl}" />