C# WPF绑定到具有listview列参数的方法的结果
我正在使用C#,WPF,.NET标准,Visual Studio。所有最新或几乎最新的版本 这是我的datacontext模型(在名为ProgrammingManagerRapi的单独库中创建):C# WPF绑定到具有listview列参数的方法的结果,c#,wpf,listview,binding,objectdataprovider,C#,Wpf,Listview,Binding,Objectdataprovider,我正在使用C#,WPF,.NET标准,Visual Studio。所有最新或几乎最新的版本 这是我的datacontext模型(在名为ProgrammingManagerRapi的单独库中创建): 公共类main模型 { 公共列表项目{get;set;} ... } 其中包含定义如下的Project类型的对象列表(在单独的库编程ManageRapi中,在目录模型中),一些属性和一些方法: public class Project { public int Id { get; set;
公共类main模型
{
公共列表项目{get;set;}
...
}
其中包含定义如下的Project类型的对象列表(在单独的库编程ManageRapi中,在目录模型中),一些属性和一些方法:
public class Project
{
public int Id { get; set; }
...
public TimeSpan? TotalWorkedTime(bool subtasksIncluded = true)
{
if (Id < 0)
return null;
else
return new TimeSpan(...);
}
...
}
公共类项目
{
公共int Id{get;set;}
...
公共时间跨度?总工作时间(bool subtasksinclude=true)
{
if(Id<0)
返回null;
其他的
返回新的时间跨度(…);
}
...
}
在主窗口中,我有一个ListView,我想用它列出项目及其属性。我有很多属性和一些方法,它们根据布尔参数返回值 我了解到,在这种情况下,我应该使用ObjectDataProvider,因此我尝试如下:
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:API.Models="clr-namespace:ProgrammingManagerAPI.Models;assembly=ProgrammingManagerAPI"
<Window.Resources>
<ObjectDataProvider x:Key="yourStaticData"
ObjectType="{x:Type API.Models:Project}"
MethodName="TotalWorkedTime" >
<ObjectDataProvider.MethodParameters>
<s:Boolean>false</s:Boolean>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid Grid.Row="1" Grid.Column="0" Margin="10">
<ListView Margin="10" ItemsSource="{Binding Projects}" HorizontalAlignment="Center" HorizontalContentAlignment="Center">
<ListView.View>
<GridView>
<GridViewColumn HeaderContainerStyle="{StaticResource ListViewStyle}" Header="Id" DisplayMemberBinding="{Binding Id}" />
<GridViewColumn HeaderContainerStyle="{StaticResource ListViewStyle}" Header="TotalWorkedTime" DisplayMemberBinding="{Binding Path=., Source={StaticResource yourStaticData}}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
xmlns:s=“clr命名空间:系统;程序集=mscorlib”
xmlns:API.Models=“clr命名空间:ProgrammingManagerAPI.Models;assembly=ProgrammingManagerAPI”
假的
对函数TotalWorkedTime的调用被触发,因为断点被命中。但只命中一次,而我已经创建了4个对象进行测试。
此外,它像静态函数一样命中,不像其他属性那样针对对象的每个实例。在即时窗口中,我试图查看哪些是其他属性,哪些是空属性。当Id列被点击时,所有属性都可用于项目的每个实例。
此外,我观察到它在调用Id属性getter之前被命中
我尝试过很多版本,比如无路径、绑定和其他许多方式
任何人都可以指出我的错误吗?
对象数据提供程序
在您有一个对象实例(或静态类)要绑定到,但您使用的是项控件(列表视图
)时非常有用,这会使事情更加复杂
你需要的是一份工作。它通过调用函数并返回结果来获取对象并“转换”它。老实说,我希望能通过谷歌搜索找到一个,但我没能找到。我想我可能迟早会使用类似的东西,所以我继续建造了一个。这支持任何类型的对象,其任何函数名包含任意数量的参数
public class FunctionConverter : IValueConverter
{
public string FunctionName { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.GetType().GetMethod(FunctionName).Invoke(value, (object[])parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
下面是一个您可以如何使用它的示例:
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
TestInstance = new Test();
InitializeComponent();
}
public Test TestInstance { get; set; }
}
public class Test
{
public string Foo(string bar)
{
return bar;
}
}
MainWindow.xaml:
<Grid>
<Grid.Resources>
<KHS:FunctionConverter x:Key="FuncCon" FunctionName="Foo"/>
</Grid.Resources>
<TextBlock>
<TextBlock.Text>
<Binding Path="TestInstance" Converter="{StaticResource FuncCon}">
<Binding.ConverterParameter>
<x:Array Type="sys:Object">
<sys:String>Hello World</sys:String>
</x:Array>
</Binding.ConverterParameter>
</Binding>
</TextBlock.Text>
</TextBlock>
</Grid>
你好,世界
将转换器声明为资源,就像对ObjectDataProvider
所做的那样,并将FunctionName
设置为要调用的函数的名称。然后转换器使用运行该函数并返回结果
您可以通过绑定的ConverterParameter
属性传递函数的参数,这将允许您为列表中的不同项传递不同的值。在本例中,我将字符串“Hello World”
传递给函数Foo
,该函数只返回传递的内容
最后几点注意:这个转换器只有一种工作方式。所提供的转换器不检查null
,并且在未找到FunctionName
时没有适当的处理。使用这样的绑定不允许像依赖项属性那样提供更新通知。为什么不简单地使用TotalWorkedTime属性并像DisplayMemberBinding=“{binding TotalWorkedTime}”
那样绑定到它,因为它是参数化的。我至少有几个(目前)方法根据某些需求返回值。如果我有3个参数,我需要用getter生成8个属性。但是如果我有5个或6个参数,它将是完全无法维护的。你将不需要同样数量的ObjectDataProviders?这就是你的意思。你说得对。然而,我不想弄乱我的API项目。你能提出一些解决办法吗?我的意思是只要告诉我一些对我的案子有用的东西?我不想以包含数百个属性的对象结束,这些属性的getter包括TotalWorkedTime1、TotalWorkedTime2、TotalWorkedTime3、…、TotalWorkedTime999。我相信WPF是如此灵活,所以它允许使用一些更智能的方式,而且肯定有人和我有类似的问题。编辑:顺便说一句,谢谢你的评论:)你是正确的。对不起,但对我来说,完全不清楚为什么应该显示在ItemsControl中的项应该有这么多属性。您希望在该列表视图中有多少列?属性不应该超过大致的列数。非常感谢。我已登录以感谢您。你是WPF的英雄。很有魅力。@ninidow359我很乐意。
<Grid>
<Grid.Resources>
<KHS:FunctionConverter x:Key="FuncCon" FunctionName="Foo"/>
</Grid.Resources>
<TextBlock>
<TextBlock.Text>
<Binding Path="TestInstance" Converter="{StaticResource FuncCon}">
<Binding.ConverterParameter>
<x:Array Type="sys:Object">
<sys:String>Hello World</sys:String>
</x:Array>
</Binding.ConverterParameter>
</Binding>
</TextBlock.Text>
</TextBlock>
</Grid>