在 RadDataFilter 中使用对象集合作为过滤器

发布于 2024-12-10 11:40:04 字数 5142 浏览 0 评论 0原文

我有一个 Silverlight 应用程序,在其中使用 RadDataFilter。此 RadDataFilter 使用自定义对象列表作为 testComboBox 的数据源。当用户单击“测试”按钮时,过滤器值始终设置为“取消设置”。例如,如果我使用下面的代码,我总是看到“Priority IsEqualTo”。但是,如果我使用字符串值列表作为 testComboBox 的数据源,则一切正常。这是我的代码:

<UserControl.Resources>
  <DataTemplate x:Key="priorityTemplate">
    <telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title" SelectedValue="{Binding Path=Value, Mode=TwoWay, FallbackValue=null}" SelectionChanged="testComboBox_SelectionChanged">
                <telerik:RadComboBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel MinWidth="320" />
                    </ItemsPanelTemplate>
                </telerik:RadComboBox.ItemsPanel>               
            </telerik:RadComboBox>
        </DataTemplate>

        <DataTemplate x:Key="locationTemplate"></DataTemplate>

        <DataTemplate x:Key="typeTemplate"></DataTemplate>

        <code:MyEditorTemplateSelector x:Key="myEditorTemplate">
            <code:MyEditorTemplateSelector.EditorTemplateRules>
                <code:MyEditorTemplateRule PropertyName="Priority" DataTemplate="{StaticResource priorityTemplate}" />
                <code:MyEditorTemplateRule PropertyName="Location" DataTemplate="{StaticResource locationTemplate}" />
                <code:MyEditorTemplateRule PropertyName="TypeName" DataTemplate="{StaticResource typeTemplate}" />               
            </code:MyEditorTemplateSelector.EditorTemplateRules>
           </code:MyEditorTemplateSelector>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Button Content="Test" Height="30" Width="90" Margin="0,0,0,8" HorizontalAlignment="Left" Click="Button_Click" />
        <telerik:RadDataFilter x:Name="filter" Grid.Row="1" EditorCreated="filter_EditorCreated" AutoGenerateItemPropertyDefinitions="False" EditorTemplateSelector="{StaticResource myEditorTemplate}" Loaded="filter_Loaded" />
    </Grid>

这是我的代码隐藏的相关部分:

private void filter_Loaded(object sender, RoutedEventArgs e)
{
    ItemPropertyDefinition priorityDefinition = new ItemPropertyDefinition("Priority", typeof(string), "Priority");
    filter.ItemPropertyDefinitions.Add(priorityDefinition);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    string rules = string.Empty;
    foreach (FilterDescriptor description in filter.FilterDescriptors)
        rules += description.ToString() + "\n";
    MessageBox.Show(rules);
}

private void filter_EditorCreated(object sender, EditorCreatedEventArgs e)
{
    switch (e.ItemPropertyDefinition.PropertyName)
    {
        case "Priority":
            // This works
            List<string> options = new List<string>() { "High", "Low" };
            //(RadComboBox)(e.Editor)).ItemsSource = options;

            // This doesn't
            List<Priority> priorities = new List<Priority>();
            priorities.Add(new Priority("High", true));
            priorities.Add(new Priority("Low", false));
            ((RadComboBox)(e.Editor)).ItemsSource = priorities;

            break;
    }
}

这是 Priority.cs 的定义:

public class Priority
{
    public string Title { get; set; }

    public bool Val { get; set; }

    public Priority(string title, bool val)
    {
        this.Title = title;
        this.Val = val;
    }
}

最后,这是模板选择器代码:

public class MyEditorTemplateSelector : DataTemplateSelector
{
    private List<MyEditorTemplateRule> templateRules = new List<MyEditorTemplateRule>();
    public List<MyEditorTemplateRule> EditorTemplateRules
    {
        get { return templateRules; }
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ItemPropertyDefinition propertyDefinition = (ItemPropertyDefinition)item;
        foreach (MyEditorTemplateRule rule in templateRules)
        {
            // Select the appropriate template for each property.
            if (rule.PropertyName == propertyDefinition.PropertyName)
            {
                return rule.DataTemplate;
            }
        }
        return base.SelectTemplate(item, container);
    }
}

public class MyEditorTemplateRule
{
    private string propertyName;
    public string PropertyName
    {
        get
        {
            return this.propertyName;
        }
        set
        {
            this.propertyName = value;
        }
    }

    private DataTemplate dataTemplate;
    public DataTemplate DataTemplate
    {
        get
        {
            return this.dataTemplate;
        }
        set
        {
            this.dataTemplate = value;
        }
    }
}

如何在编辑器模板中使用自定义类型作为过滤器选项?

谢谢你!

I have a Silverlight application in which I am using the RadDataFilter. This RadDataFilter uses a list of custom objects as the data source for the testComboBox. When a user clicks the "Test" button, the filter value is always set to "Unset". For instance, if I use the code below, I always see "Priority IsEqualTo ". However, if I use use a List of string values as the data source for testComboBox, everything works fine. Here is my code:

<UserControl.Resources>
  <DataTemplate x:Key="priorityTemplate">
    <telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title" SelectedValue="{Binding Path=Value, Mode=TwoWay, FallbackValue=null}" SelectionChanged="testComboBox_SelectionChanged">
                <telerik:RadComboBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel MinWidth="320" />
                    </ItemsPanelTemplate>
                </telerik:RadComboBox.ItemsPanel>               
            </telerik:RadComboBox>
        </DataTemplate>

        <DataTemplate x:Key="locationTemplate"></DataTemplate>

        <DataTemplate x:Key="typeTemplate"></DataTemplate>

        <code:MyEditorTemplateSelector x:Key="myEditorTemplate">
            <code:MyEditorTemplateSelector.EditorTemplateRules>
                <code:MyEditorTemplateRule PropertyName="Priority" DataTemplate="{StaticResource priorityTemplate}" />
                <code:MyEditorTemplateRule PropertyName="Location" DataTemplate="{StaticResource locationTemplate}" />
                <code:MyEditorTemplateRule PropertyName="TypeName" DataTemplate="{StaticResource typeTemplate}" />               
            </code:MyEditorTemplateSelector.EditorTemplateRules>
           </code:MyEditorTemplateSelector>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Button Content="Test" Height="30" Width="90" Margin="0,0,0,8" HorizontalAlignment="Left" Click="Button_Click" />
        <telerik:RadDataFilter x:Name="filter" Grid.Row="1" EditorCreated="filter_EditorCreated" AutoGenerateItemPropertyDefinitions="False" EditorTemplateSelector="{StaticResource myEditorTemplate}" Loaded="filter_Loaded" />
    </Grid>

Here is the relevant parts of the my code-behind:

private void filter_Loaded(object sender, RoutedEventArgs e)
{
    ItemPropertyDefinition priorityDefinition = new ItemPropertyDefinition("Priority", typeof(string), "Priority");
    filter.ItemPropertyDefinitions.Add(priorityDefinition);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    string rules = string.Empty;
    foreach (FilterDescriptor description in filter.FilterDescriptors)
        rules += description.ToString() + "\n";
    MessageBox.Show(rules);
}

private void filter_EditorCreated(object sender, EditorCreatedEventArgs e)
{
    switch (e.ItemPropertyDefinition.PropertyName)
    {
        case "Priority":
            // This works
            List<string> options = new List<string>() { "High", "Low" };
            //(RadComboBox)(e.Editor)).ItemsSource = options;

            // This doesn't
            List<Priority> priorities = new List<Priority>();
            priorities.Add(new Priority("High", true));
            priorities.Add(new Priority("Low", false));
            ((RadComboBox)(e.Editor)).ItemsSource = priorities;

            break;
    }
}

Here is the definition for Priority.cs:

public class Priority
{
    public string Title { get; set; }

    public bool Val { get; set; }

    public Priority(string title, bool val)
    {
        this.Title = title;
        this.Val = val;
    }
}

Finally, here is the Template selector code:

public class MyEditorTemplateSelector : DataTemplateSelector
{
    private List<MyEditorTemplateRule> templateRules = new List<MyEditorTemplateRule>();
    public List<MyEditorTemplateRule> EditorTemplateRules
    {
        get { return templateRules; }
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ItemPropertyDefinition propertyDefinition = (ItemPropertyDefinition)item;
        foreach (MyEditorTemplateRule rule in templateRules)
        {
            // Select the appropriate template for each property.
            if (rule.PropertyName == propertyDefinition.PropertyName)
            {
                return rule.DataTemplate;
            }
        }
        return base.SelectTemplate(item, container);
    }
}

public class MyEditorTemplateRule
{
    private string propertyName;
    public string PropertyName
    {
        get
        {
            return this.propertyName;
        }
        set
        {
            this.propertyName = value;
        }
    }

    private DataTemplate dataTemplate;
    public DataTemplate DataTemplate
    {
        get
        {
            return this.dataTemplate;
        }
        set
        {
            this.dataTemplate = value;
        }
    }
}

How do I use a Custom type for the filter options in a Editor Template?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

计㈡愣 2024-12-17 11:40:04

实际上,我认为当您使用字符串列表时,您可以使用以下代码:

<telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title"
SelectedValue="{Binding Path=Value, Mode=TwoWay, FallbackValue=null}"
SelectionChanged="testComboBox_SelectionChanged">

但是,例如,当您更改 DataSource 时,您使用对象集合,那么您可能会更改 DisplayMemberPath > 和 SelectedValue
对于 DadDataFilter 您不应该更改

 selectValue={Binding Path=Value, Mode=TwoWay, FallbackValue=null};

这里的 path=Value 必须与所有绑定相同。
尝试使用以下内容:

<telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title"
SelectedValue="{Binding Value, Mode=TwoWay, FallbackValue=null}"
SelectionChanged="testComboBox_SelectionChanged">

Actually, I think when you use list of string then you use following code:

<telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title"
SelectedValue="{Binding Path=Value, Mode=TwoWay, FallbackValue=null}"
SelectionChanged="testComboBox_SelectionChanged">

But, when you change your DataSource, for example, you use collection of objects then you probably change DisplayMemberPath and SelectedValue.
For DadDataFilter you should not change

 selectValue={Binding Path=Value, Mode=TwoWay, FallbackValue=null};

Here path=Value must be same of all binding.
Try to use the following:

<telerik:RadComboBox x:Name="testComboBox" MinWidth="100" DisplayMemberPath="Title"
SelectedValue="{Binding Value, Mode=TwoWay, FallbackValue=null}"
SelectionChanged="testComboBox_SelectionChanged">
最冷一天 2024-12-17 11:40:04

我在 WPF 中遇到了完全相同的问题,在徒劳地搜索解决方案时发现了您的问题,我最终找到了解决方案:

您将 ItemPropertyDefinition 的属性类型设置为字符串,但在 ItemPropertyDefinition 的绑定中code>RadComboBox 的 SelectedValue,绑定的对象 Value 类型为“Priority”。因此,解决方案是在绑定中使用 Converter 对象,Converter 类必须实现 IValueConverter

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using QUPS.Data;
using QUPS.Data.QUPSModel;

namespace QUPS.Helpers
{
    public class EntityObjectToDecimalConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
                              CultureInfo culture)
        {
            if (value is IQUPSEntityObject)
            {
                var rec = (IQUPSEntityObject)value;
                return rec.ID;
            }

            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
                                  CultureInfo culture)
        {
            if (value is IQUPSEntityObject)
            {
                var rec = (IQUPSEntityObject)value;
                return rec.ID;
            }

            return value;
        }
    }
}

这是我的 xaml 的一部分:

<DataTemplate x:Key="CriteriaRightExpressionComboBoxTemplate">
    <telerik:RadComboBox SelectedValue="{Binding Value, Mode=OneWayToSource, FallbackValue=null, Converter={StaticResource EntityObjectToDecimalConverter}}"
                             MinWidth="100"
                             ItemTemplateSelector="{StaticResource CriteriaRightExpressionComboBoxTemplateSelector}"
                             >
    </telerik:RadComboBox>
</DataTemplate>

I had exactly the same problem in WPF, found your question while googling in vain for a solution that I finally figured out:

You set the property type of your ItemPropertyDefinition to string, but in the binding of your RadComboBox's SelectedValue, the bound object Value is of type "Priority". So the solution is to use a Converter object in your binding, the Converter class must implement IValueConverter.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using QUPS.Data;
using QUPS.Data.QUPSModel;

namespace QUPS.Helpers
{
    public class EntityObjectToDecimalConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
                              CultureInfo culture)
        {
            if (value is IQUPSEntityObject)
            {
                var rec = (IQUPSEntityObject)value;
                return rec.ID;
            }

            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
                                  CultureInfo culture)
        {
            if (value is IQUPSEntityObject)
            {
                var rec = (IQUPSEntityObject)value;
                return rec.ID;
            }

            return value;
        }
    }
}

And here's the piece of my xaml:

<DataTemplate x:Key="CriteriaRightExpressionComboBoxTemplate">
    <telerik:RadComboBox SelectedValue="{Binding Value, Mode=OneWayToSource, FallbackValue=null, Converter={StaticResource EntityObjectToDecimalConverter}}"
                             MinWidth="100"
                             ItemTemplateSelector="{StaticResource CriteriaRightExpressionComboBoxTemplateSelector}"
                             >
    </telerik:RadComboBox>
</DataTemplate>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文