2011-10-17 171 views
1

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

<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; 
     } 
    } 
} 

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

谢谢!

回答

1

其实,我认为当你使用字符串列表然后使用下面的代码:

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

但是,当你改变你的DataSource,例如,您使用对象的集合,那么你可能会改变DisplayMemberPathSelectedValue 。 对于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"> 
0

我在WPF有完全相同的问题,发现你的问题而白白google搜索,我终于想出了一个解决方案:

您设置的属性类型的ItemPropertyDefinition为字符串,但在您的RadComboBoxSelectedValue的绑定中,绑定对象值的类型为“优先级”。所以解决方案是在绑定中使用对象,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>