C# 在WPF列表框中以不同方式设置每个项目

C# 在WPF列表框中以不同方式设置每个项目,c#,wpf,xaml,C#,Wpf,Xaml,我对WPF&XAML很陌生。我为任何初学者/愚蠢者/矛盾者的问题感到抱歉,因为我现在脑子里什么都混在一起了。看起来事情和使用WinForms有很大的不同,所以我尝试用WPF的方式 在我的应用程序中,我想使用ListBox 我已经完成了最简单任务所需的工作: -已将ItemsSource属性连接到我的IEnumerable实例(在我的示例中为列表)。 -在XAML中,我有ItemTemplate,到目前为止没有什么特别之处: <Label Content="{Binding ValueA}"

我对WPF&XAML很陌生。我为任何初学者/愚蠢者/矛盾者的问题感到抱歉,因为我现在脑子里什么都混在一起了。看起来事情和使用WinForms有很大的不同,所以我尝试用WPF的方式

在我的应用程序中,我想使用ListBox

我已经完成了最简单任务所需的工作: -已将ItemsSource属性连接到我的IEnumerable实例(在我的示例中为列表)。 -在XAML中,我有ItemTemplate,到目前为止没有什么特别之处:

<Label Content="{Binding ValueA}" />
<Label Content="{Binding ValueB}" />

这项工作很好,现在我想隐藏/显示其中一个标签,如果IEnumerable的成员满足某些条件。为此,我可以使用标签的可见性属性

例如:

<Label Content="{Binding ValueB}" Visibility={Binding IsValueBVisible} />

但是,如何为IEnumerable的每个成员运行代码,并提供属性IsValueBVisible的信息,即使原始成员没有它

我想到的第一个解决方案是在原始IEnumerable对象周围使用某种包装器,但包含IsValueBVisible等属性

class MyItemsSource : IEnumerable<IMyItem>, IMyItem
{
    private OtherType _source;

    public List<OtherType>: SourceList { get; set; }

    public bool IsValueBVisible
    {
        get
        {
            // now we can use _source and decide on return value
        }
    }

    public MyItem this[int index]
    {
        get
        {
            // Get original instance at index, do
            // comparisons, calculations etc.
            // return my value on which XAML can bind.
            _source = SourceList[index];

            return this;
        }
    }
}
类MyItemsSource:IEnumerable,IMyItem
{
私有OtherType_源;
公共列表:SourceList{get;set;}
公共利益是有价值的
{
得到
{
//现在我们可以使用_source并决定返回值
}
}
公共MyItem此[整数索引]
{
得到
{
//获取索引处的原始实例,执行以下操作
//比较、计算等。
//返回XAML可以绑定的值。
_source=SourceList[索引];
归还这个;
}
}
}
这只是一个草图代码

这可能会使事情复杂化很多,有没有其他更干净的方法?最后几天尽可能多地学习,但失败了。也许过几天会容易些


感谢您的帮助。

了解MVVM模式,有很多关于它的信息


目标是将您的
数据模型
包装到另一个类中,即
ViewModel
,该类实现属性(在本例中,至少
IsVisible
)以将其正确绑定到
视图

是的,您需要为您的项目创建包装:

public class MyItemWrapper
{
   public MyItemWrapper(MyItem item)
   {
     Info=item;
     IsVisible = true; 
   }
   public MyItem Info {get; set;}
   public bool IsVisible {get; set;}
}
然后您可以使用
MyItemWrapper
列表而不是
MyItem
列表:

List<MyItemWrapper> lstWrapperItems =  ... // create an instance of MyItemWrapper for each object of type MyItem
List lstWrapperItems=…//为MyItem类型的每个对象创建MyItemWrapper的实例
现在,您可以将新创建的列表分配给
ListBox.ItemsSource
,然后在
绑定中执行以下操作:


请注意,现在您不需要使用“InfoA”或“IsVisibleA”,只需在包装类中指定属性的名称。

看看如何将自定义对象绑定到列表框:这应该可以解决您的问题。
MyItemSource
中没有任何意义。它可以是ViewModel中的一个简单的
ObservableCollection
属性,其中
SomeType
具有
IsVisible
bool
属性,您不应该在ViewModel中使用
Visibility
类型)。。。。现在我注意到问题中缺少
MVVM
标记,对不起,谢谢。我以前没有使用过ObservaleCollection,现在我将阅读它。列表的原始成员(模型)没有IsVisible、Visibility等属性,但它是由“外部”决定的,类似于:if(ItemAtIndex是IHasBValue)&&(ItemAtIndex.Value>100)…谢谢,您能告诉我是否有办法在不创建新实例的情况下“动态”包装吗?(如果是初学者的问题,很抱歉)@Bojan:我已经更新了答案,在包装器类中添加了一个构造函数。因此,您可以简单地使用
wrapper=newmyitemwrapper(myItem)
。您需要创建一个实例,以便设置
IsVisible
的值。如果您不需要
IsVisible
,则无需使用包装器…再次感谢。我将尝试提供更多细节:IsVisible(稍后可能会添加IsImportantText等)是一个基于其他模型属性计算(而不是存储)的属性。所以,我只需要包装器向XAML提供可视信息(在我的例子中是Visibility属性),但这些信息在不同的列表成员之间是不同的。如果XAML中有类似的东西,我的理想选择是:
。我试图在我的示例中使用一些MVVM的残余。IsVisible是从MyItemsSource类调用的。我尝试过实现IEnumerable,因为它为我提供了请求项的索引。对WPF来说还是新手,也许我混合了一些东西:)