OK, I've solved both of my problems - with binded value not saved to data source and with not updating interface. The solution which I came is rather simple, but I still don't understand how INotifyPropertyChange interface is working. Below full, working solution with additional two methods.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace TriStateRadioControlLibrary
{
[System.ComponentModel.DefaultBindingProperty("Checked")]
public partial class TriStateRadio : UserControl, INotifyPropertyChanged
{
public String TextTrueRadio { get { return radioButton1.Text; } set { radioButton1.Text = value; } }
public String TextFalseRadio { get { return radioButton2.Text; } set { radioButton2.Text = value; } }
public String TextNullRadio { get { return radioButton3.Text; } set { radioButton3.Text = value; } }
public Nullable<bool> _checked;
public Nullable<bool> Checked
{
get { return _checked; }
set
{
if (value != _checked)
{
_checked = value;
OnPropertyChanged("Checked");
}
}
}
private void CheckChanged()
{
switch (_checked)
{
case true:
radioButton1.Checked = true;
break;
case false:
radioButton2.Checked = true;
break;
case null:
radioButton3.Checked = true;
break;
default:
throw new Exception("Error selecting TriStateRadio state!");
}
}
public TriStateRadio()
{
InitializeComponent();
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButton1.Checked == true)
{
this.Checked = true;
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButton2.Checked == true)
{
this.Checked = false;
}
}
private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButton3.Checked == true)
{
this.Checked = null;
}
}
#region PropertyChangeNotification
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
public void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void TriStateRadio_Load(object sender, EventArgs e)
{
PropertyChanged += new PropertyChangedEventHandler(TriStateRadio_PropertyChanged);
CheckChanged();
}
void TriStateRadio_PropertyChanged(object sender, EventArgs e)
{
CheckChanged();
}
}
}
As I thought, it was the missing delegate :)