2
votes

I am using WPF having a strange issue with RadListBox SelectedItem databinding, trying to figure out but no luck. Following is my scenario

  1. I am using Telerik Controls (RadListBox, and RadButton)
  2. RadButton is placed inside a ItemsControl, RadListBox and ItemsControl are bind to same ItemsSource.
  3. I am using PRISM and MVVM.
  4. What I want is when I click on button, the same item is selected from RadListBox automatically, (This part working fine).
  5. Problem: As soon as I click on any item of RadListBox and then click back on any button the item selection stops working.
  6. Edit: I tried the same thing with standard WPF ListBox by adding attached behavior for selection changed event and attached property of Command and CommandParameter, it works fine, so it looks like an issue with Telerik RadListBox ?

Now let me come to code.

ViewModel Class

public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    public DelegateCommand<object> StudentSelected { get; set; }
    public DelegateCommand<object> ButtonPressed { get; set; }

    private void OnStudentSelected(object par)
    {
        //Debugger.Break();
        if (handled == false)
        {
            Student std = par as Student;
            if (std != null)
            {
                SelectedStudent = std;
            }
        }
        handled = false;
    }

    private void OnButtonPressed(object par)
    {
        //Debugger.Break();
        handled = true;
        String std = par as String;
        if (std != null)
        {
            foreach (Student st in _students)
            {
                if (st.Name.Equals(std))
                {
                    SelectedStudent = st;
                    break;
                }
            }
        }
    }    

    private Student _selectedstudent;
    private bool handled = false;


    public MainViewModel()
    {
        StudentSelected = new DelegateCommand<object>(OnStudentSelected);
        ButtonPressed = new DelegateCommand<object>(OnButtonPressed);
    }

    public Student SelectedStudent
    {
        get
        {
            return _selectedstudent;
        }
        set
        {
            _selectedstudent = value;
            OnPropertyChanged("SelectedStudent");
        }
    }


    private ObservableCollection<Student> _students;
    public ObservableCollection<Student> Students
    {
        get
        {
            return _students;
        }
        set
        {
            _students = value;
            OnPropertyChanged("Students");
        }
    }
}

public class Student
{
    public String Name { get; set; }
    public String School { get; set; }
}

MainView XAML

    <telerik:RadListBox Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Students}" Command="{Binding StudentSelected}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=SelectedItem}" SelectedItem="{Binding SelectedStudent, Converter={StaticResource DebugConverter}}">
<!-- The above debug converter is just for testing binding, as long as I keep on clicking button the Converter is being called, but the moment I click on RadListBoxItem the Converter is not called anymore, even when I click back on buttons -->
                <telerik:RadListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"></TextBlock>
                    </DataTemplate>
                </telerik:RadListBox.ItemTemplate>
            </telerik:RadListBox>
            <Label Grid.Row="0" Grid.Column="1" Content="{Binding SelectedStudent.Name}"></Label>
            <StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal">
                <ItemsControl ItemsSource="{Binding Students}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <telerik:RadButton Width="100" Height="70" Content="{Binding Name}" Command="{Binding RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type Window}}, Path=DataContext.ButtonPressed}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}">
                        </telerik:RadButton>
                    </DataTemplate>    
                    </ItemsControl.ItemTemplate>

                </ItemsControl>
            </StackPanel>

and finally populating the ViewModel and setting the Datacontext

MainViewModel mvm = new MainViewModel();
            ObservableCollection<Student> students = new ObservableCollection<Student>();
            students.Add(new Student { Name = "Student 1", School = "Student 1 School" });
            students.Add(new Student { Name = "Student 2", School = "Student 2 School" });
            students.Add(new Student { Name = "Student 3", School = "Student 3 School" });

            mvm.Students = students;

            //Bind datacontext
            this.DataContext = mvm;

Please give your suggestions and share you expertise from WPF Jargon?

1

1 Answers

6
votes

Finally I figured out the issue, I just need to replace the RadListBox SelectedItem binding to TwoWay

<telerik:RadListBox Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Students}" Command="{Binding StudentSelected}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=SelectedItem}" SelectedItem="{Binding SelectedStudent, Mode,TwoWay, Converter={StaticResource DebugConverter}}">