Silverlight数据绑定-将ValueConverter绑定到视图模型上的属性

Silverlight数据绑定-将ValueConverter绑定到视图模型上的属性,silverlight,data-binding,mvvm,treeview,Silverlight,Data Binding,Mvvm,Treeview,让我们假设我有以下xaml <UserControl.Resources> <local:ViewModel x:Name="viewModel" /> <local:LoadChildrenValueConverter x:Name="valueConverter" /> </UserControl.Resources> <UserControl.DataContext> <Binding Source

让我们假设我有以下xaml

<UserControl.Resources>
    <local:ViewModel x:Name="viewModel" />
    <local:LoadChildrenValueConverter x:Name="valueConverter" />
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource viewModel}" />
</UserControl.DataContext>

<Grid x:Name="LayoutRoot" Background="White">
    <control:TreeView ItemsSource="{Binding Root}">
        <control:TreeView.ItemTemplate>
            <control:HierarchicalDataTemplate ItemsSource="{Binding Converter={StaticResource valueConverter}}">
                <TextBlock Text="{Binding}" />
            </control:HierarchicalDataTemplate>
        </control:TreeView.ItemTemplate>
    </control:TreeView>
</Grid>


…和下面的代码一起使用

using System; using System.Collections.ObjectModel; using System.Windows.Data; namespace SilverlightViewModelSpike { public class ViewModel { public ViewModel() { Root = new ObservableCollection() { "Item 1", "Item 2", "Item 3", }; } public ObservableCollection Root { get; private set; } } public class LoadChildrenValueConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return new ObservableCollection() { "Item 1", "Item 2", "Item 3", }; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } } 使用制度; 使用System.Collections.ObjectModel; 使用System.Windows.Data; 名称空间SilverlightViewModelSpike { 公共类视图模型 { 公共视图模型() { Root=新的ObservableCollection(){“项目1”、“项目2”、“项目3”,}; } 公共可观测集合根{get;private set;} } 公共类LoadChildrenValueConverter:IValueConverter { 公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性) { 返回新的observeCollection(){“Item 1”、“Item 2”、“Item 3”,}; } 公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性) { 抛出新的NotImplementedException(); } } } 这正如预期的那样工作,但我有两个单独的类来获取视图所需的数据(假设ViewModel和LoadChildrenValueConverter从web服务中提取数据,而不是返回硬编码数据),这感觉是错误的。这里有更好的解决方案吗?我在想也许是这样的

using System; using System.Collections.ObjectModel; using System.Windows.Data; namespace SilverlightViewModelSpike { public class ViewModel { public ViewModel() { Root = new ObservableCollection() { "Item 1", "Item 2", "Item 3", }; ValueConverter = new LoadChildrenValueConverter(); } public ObservableCollection Root { get; private set; } public LoadChildrenValueConverter ValueConverter { get; private set; } } public class LoadChildrenValueConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return new ObservableCollection() { "Item 1", "Item 2", "Item 3", }; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } } 使用制度; 使用System.Collections.ObjectModel; 使用System.Windows.Data; 名称空间SilverlightViewModelSpike { 公共类视图模型 { 公共视图模型() { Root=新的ObservableCollection(){“项目1”、“项目2”、“项目3”,}; ValueConverter=新的LoadChildrenValueConverter(); } 公共可观测集合根{get;private set;} public LoadChildrenValueConverter ValueConverter{get;private set;} } 公共类LoadChildrenValueConverter:IValueConverter { 公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性) { 返回新的observeCollection(){“Item 1”、“Item 2”、“Item 3”,}; } 公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性) { 抛出新的NotImplementedException(); } } } 。。。但是我不能让这条线工作


…即使这样似乎也不是一个很好的解决方案。有人对此有一个干净的解决方案吗?

因为您使用的是ViewModel,它位于实际模型和视图之间,我想知道直接在其中实现IValueConverter逻辑是否更容易。有点像:

public class ViewModel
{
    public ObservableCollection Root { get; set: }

    public ObservableCollection Children
    {
        get { /* return children items */ }
    }
}
然后,您可以直接绑定到第二个属性:

<control:HierarchicalDataTemplate ItemsSource="{Binding Children}">
现在你应该能够说:

<control:HierarchicalDataTemplate 
    ItemsSource="{Binding Converter={x:Static local:ViewModel.ChildrenConverter}}">
现在您可以执行以下操作:

<control:HierarchicalDataTemplate
    ItemsSource="{Binding Converter={StaticResource ViewModel}}">

对不起,伙计们,我有点搞不清楚你们想在这里做什么。。。不管怎样,从标题上看,似乎您希望将值转换器中的属性转换为值转换器中的属性。首先看一看我写的一篇文章,其中详细解释了如何做到这一点:

所以,您要做的是在LoadChildrenValueConverter中创建一个ObvervableCollection依赖项属性,为了参数起见,让我们称之为Children

然后在xaml中,您可以将LoadChildrenValueConverter更改为如下内容:

这样,您只需要从视图模型中调用一次web服务,然后就可以使用值转换器共享视图模型中的ObvervableCollection


希望能有帮助。

这正是我想要的。但是,我认为Silverlight不允许绑定中的x:Static。那不是真的吗?啊,你说得对。我没有注意到你把你的问题标记为Silverlight。我会在答案后面加上一个选项,以防万一,谢谢你的帮助。你在Edit2中提出的想法实际上就是我的出发点。我希望有一个更干净的解决方案,但我现在似乎不喜欢。看到其他人得出同样的结论确实有帮助。至少我不觉得这是一个愚蠢的解决方案:)
public class ViewModel : IValueConverter
{
    // move your Convert and ConvertBack methods into here
}
<control:HierarchicalDataTemplate
    ItemsSource="{Binding Converter={StaticResource ViewModel}}">