1

I am making a program using similar structure as Data Binding Demo (http://code.msdn.microsoft.com/Data-Binding-Demo-82a17c83).

I am right now trying to implement radio buttons inside my list box data template. My aim is to modify the 'selected' value of the proper Question object. I guess it is possible by giving the proper Binding to 'Checked' property of the 2 RadioButton elements in my template but so far I have not been able to do that. My other attempt was to do this in code behind but I also failed here. Thank you for any advise.

Question class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;


namespace WpfApplication1
{
    public class Question : INotifyPropertyChanged
    {
        private int ID;
        private int question_number;
        private string question;
        private bool is_private;
        private bool selected;

        public event PropertyChangedEventHandler PropertyChanged;

        public int _ID
        {
            get { return this.ID; }
            set { this.ID = value; OnPropertyChanged("_ID"); }
        }

        public int _question_number
        {
            get { return this.question_number; }
            set { this.question_number = value; OnPropertyChanged("_question_number"); }
        }

        public string _question
        {
            get { return this.question; }
            set { this.question = value; OnPropertyChanged("_question"); }
        }

        public bool _is_private
        {
            get { return this.is_private; }
            set { this.is_private = value; OnPropertyChanged("_is_private"); }
        }

        public bool _selected
        {
            get { return this.selected; }
            set { this.selected = value; OnPropertyChanged("_selected"); }
        }

        public Question(int ID, int question_number, string question, bool is_private, bool selected)
        {
            this.ID = ID;
            this.question = question;
            this.question_number = question_number;
            this.is_private = is_private;
            this.selected = selected;
        }

        protected void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}

xaml file

<Window x:Class="WpfApplication1.Audyt_window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Audyt" 
        xmlns:src="clr-namespace:WpfApplication1" 
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        WindowStartupLocation="CenterScreen"
        >

    <Window.Resources>

        <CollectionViewSource Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=Questions}" x:Key="questions_collection" />

        <Style x:Key="text_style" TargetType="TextBlock">
            <Setter Property="Foreground" Value="#333333" />
        </Style>

        <DataTemplate x:Key="Questions_Template" DataType="{x:Type src:Question}">
            <Border BorderThickness="2" BorderBrush="Brown" Padding="7" Name="Question_List_Border" Margin="3" Width="365">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="20"/>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="60"/>
                        <ColumnDefinition Width="60"/>
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Row="0" Grid.Column="0"
                               Name="textblock_ID"
                               Style="{StaticResource text_style}"
                               Text="ID: "
                               >
                    </TextBlock>
                    <TextBlock Grid.Row="0" Grid.Column="1"
                               Name="textblock2_ID"
                               Style="{StaticResource text_style}"
                               Text="{Binding Path=_ID}"
                               >
                    </TextBlock>
                    <TextBlock Grid.Row="1" Grid.Column="0"
                               Name="textblock_question_number"
                               Style="{StaticResource text_style}"
                               Text="Val"
                               >
                    </TextBlock>
                    <TextBlock Grid.Row="1" Grid.Column="1"
                               Name="textblock2_question_number"
                               Style="{StaticResource text_style}"
                               Text="{Binding Path=_question_number}"
                               >
                    </TextBlock>
                    <TextBlock Grid.Row="0" Grid.Column="2" Grid.RowSpan="3" TextWrapping="Wrap"
                               Name="textblock_question"
                               Style="{StaticResource text_style}"
                               Text="{Binding Path=_question}"
                               >
                    </TextBlock>
                    <RadioButton GroupName="{Binding Path=_ID}" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" Checked="RadioButtons_Yes" Margin="10,17,11,17">Tak</RadioButton>
                    <RadioButton GroupName="{Binding Path=_ID}" Grid.Row="0" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center" Checked="RadioButtons_No" Margin="10,17,11,17">Nie</RadioButton>
                </Grid>
            </Border>
        </DataTemplate>

    </Window.Resources>

    <Border Padding="10">
        <Grid>

            <ListBox Name="Questions_View_List" HorizontalAlignment="Left" VerticalAlignment="Top" 
                 Height="525" Width="400" Margin="0,0,0,0" BorderThickness="2" BorderBrush="DimGray"
                 ItemsSource="{Binding Source={StaticResource questions_collection}}"  
                 ItemTemplate="{StaticResource Questions_Template}"
                 SelectionMode="Single"
                 SelectedValue="{Binding Path=_ID}" 
                 SelectedValuePath="{Binding Path=_ID}"
                 SelectionChanged="Questions_View_List_SelectionChanged"
                 >
            </ListBox>


        </Grid>
    </Border>
</Window>

code behind

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.ComponentModel;


namespace WpfApplication1
{
    public partial class Audyt_window : Window
    {       
        CollectionViewSource questions_collection;

        private ObservableCollection<Question> questions = new ObservableCollection<Question>();
        public ObservableCollection<Question> Questions
        {
            get { return this.questions; }
            set { this.questions = value; }
        }

        public Audyt_window()
        {
            DataContext = this;  
            load_temp_data();
            InitializeComponent();
            questions_collection = (CollectionViewSource)(this.Resources["questions_collection"]);
        }

        private void load_temp_data()
        {
            Question que1 = new Question(1, 2, "Question1", false, false);
            Question que2 = new Question(2, 1, "Question2", false, false);
            Question que3 = new Question(3, 0, "Question3", false, false);
            this.Questions.Add(que1);
            this.Questions.Add(que2);
            this.Questions.Add(que3);
        }

        private void Questions_View_List_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
           // Question question_temp = (Question)((ListBox)e.Source).SelectedValue;

        }

        private void RadioButtons_Yes(object sender, RoutedEventArgs e)
        {
            //Question question_temp = (Question)((ListBox)e.Source(RadioButton)e.Source; // Can't really figure this out ;/ 
            //Variables.selected_question = question_temp._ID;


        }

        private void RadioButtons_No(object sender, RoutedEventArgs e)
        {


        }

    }
}
Quass1m
  • 315
  • 2
  • 4
  • 11
  • If first RadioButton is responsible for setting _selected to yes/no then set in it IsChecked="{Binding _selected, Mode=TwoWay}", both radiobutton are assigned to the same groupname so you can select only one of them concurrently. – Maximus Aug 19 '14 at 14:32
  • Thank you. This was actually the easiest yet working solution. – Quass1m Aug 19 '14 at 15:22

2 Answers2

0

While your question is still a little unclear because you have only used a few lines of words compared with your million lines of code, I believe that I know what you are after. I think that you will need to create an enum to differentiate between the different answers to your questions... perhaps something as simple as this?:

public enum Answer { A, B, C, D ... }

Now that you have an enum, you can use that on the different RadioButtons, along with an EnumToBoolConverter:

<StackPanel>
    <RadioButton IsChecked="{Binding AnswerProperty, Converter={StaticResource 
        EnumToBoolConverter}, ConverterParameter=A}" Content="Answer A" />
    <RadioButton IsChecked="{Binding AnswerProperty, Converter={StaticResource 
        EnumToBoolConverter}, ConverterParameter=B}" Content="Answer B" />
    <RadioButton IsChecked="{Binding AnswerProperty, Converter={StaticResource 
        EnumToBoolConverter}, ConverterParameter=C}" Content="Answer C" />
    <RadioButton IsChecked="{Binding AnswerProperty, Converter={StaticResource 
        EnumToBoolConverter}, ConverterParameter=D}" Content="Answer D" />
</StackPanel>

The AnswerProperty here relates to your 'selected' value of the proper Question object as you called it. Of course, you'll need to change that property type to the type of your enum now. You can find many different versions of the EnumToBoolConverter online and there is one in the answer to the How to bind RadioButtons to an enum? question here on Stack Overflow.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183
0

Try this , As you want to change the Question Object on selection of Radio

        <RadioButton Command="{Binding RadioCommand}" CommandParameter="Tak" GroupName="MyRadioGroup">Tak</RadioButton>
    <RadioButton Command="{Binding RadioCommand}" CommandParameter="Nie"  GroupName="MyRadioGroup">Nie</RadioButton>

Question.cs

    public class Question : INotifyPropertyChanged
{
   //your existing code
    //....
    //.....
    //Add Command to your Question class as below

    MyCommand radioCommand;
    public MyCommand RadioCommand
    {
        get { return radioCommand ?? (radioCommand = new MyCommand(OnRadioCommand, () => true)); } 
    }

    void OnRadioCommand(object obj)
    {
        if (obj != null)
        {
            var checkedRadiochecked = obj.ToString();
            //checkedRadiochecked  will have either Tak or Nie according to 
            //  RadioButton checked
            //do your stuff of changing this object here
        }
    }
}

}

Mycommand or you can use other like Relaycommand

    public class MyCommand : ICommand
{

    Action<object> executeAction;
    Func<bool> canExecute;

    public MyCommand(Action<object> executeAction, Func<bool> canExecute)
    {
        this.executeAction = executeAction;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (canExecute != null)
            return canExecute();
        else
            return true;
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)  
            CanExecuteChanged(this, new EventArgs());
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (executeAction != null)
            executeAction(parameter);
    }
}
yo chauhan
  • 12,079
  • 4
  • 39
  • 58