The exception you are getting, due to the cmbTest.SelectedValue property being null, happens because when the user selects "Other" in the ComboBox, you execute this statement:
BindingOperations.ClearBinding(cmbTest, ComboBox.TextProperty);
I.e. when you clear the binding to the ComboBox's Text property, the binding system resets the property value to null. This causes your event handler to be called recursively, but this time the SelectedValue property is null, and dereferencing causes the NullReferenceException.
You could fix this by checking the property value for null before trying to dereference it. But while this would avoid the exception, it won't change the fact that changing the bindings dynamically causes changes in the various bound values, in a variety of undesirable ways.
Instead of trying to get your current approach to work, it's my opinion you should try to work more closely with the binding system itself to produce the desired results.
One way to do this would be to follow the suggestion in my comment:
"Would it be appropriate to simply bind each of the ComboBox and TextBox to two separate properties and resolve the "other" aspect entirely in code-behind rather than via additional binding logic?"
And in fact, this is essentially the approach provided in the answer from Bizz. IMHO his answer is useful and worth taking a look at. That said, he implemented it somewhat differently from how I would have, so I will share my version of that particular approach:
XAML:
<Window x:Class="TestSO28524422ComboAndTextToProperty.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestSO28524422ComboAndTextToProperty"
        Title="MainWindow" Height="350" Width="525">
  <StackPanel>
    <StackPanel.DataContext>
      <local:Person/>
    </StackPanel.DataContext>
    <ComboBox Name="cmbTest" Width="140" Margin="5" SelectedValuePath="Content"
              SelectedValue="{Binding ComboBoxText}">
      <ComboBoxItem Content="Name1"/>
      <ComboBoxItem Content="Name2"/>
      <ComboBoxItem Content="Name3"/>
      <ComboBoxItem Content="Name4"/>
      <ComboBoxItem Content="Other" IsSelected="{Binding IsOtherSelected}"/>
    </ComboBox>
    <TextBox Name="txtTest"  Width="140" Margin="5"
             Text="{Binding TextBoxText, UpdateSourceTrigger=PropertyChanged}">
      <TextBox.Style>
        <Style TargetType="TextBox">
          <Style.Triggers>
            <DataTrigger Binding="{Binding IsOtherSelected}" Value="False">
              <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
          </Style.Triggers>
        </Style>
      </TextBox.Style>
    </TextBox>
    <TextBlock Text="{Binding Name}"/>
  </StackPanel>
</Window>
C#:
public class Person : DependencyObject
{
    public static readonly DependencyProperty IsOtherSelectedProperty =
        DependencyProperty.Register("IsOtherSelected", typeof(bool), typeof(Person));
    public static readonly DependencyProperty ComboBoxTextProperty =
        DependencyProperty.Register("ComboBoxText", typeof(string), typeof(Person),
        new PropertyMetadata(OnComboBoxTextChanged));
    public static readonly DependencyProperty TextBoxTextProperty =
        DependencyProperty.Register("TextBoxText", typeof(string), typeof(Person),
        new PropertyMetadata(OnTextBoxTextChanged));
    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(Person));
    public bool IsOtherSelected
    {
        get { return (bool)GetValue(IsOtherSelectedProperty); }
        set { SetValue(IsOtherSelectedProperty, value); }
    }
    public string ComboBoxText
    {
        get { return (string)GetValue(ComboBoxTextProperty); }
        set { SetValue(ComboBoxTextProperty, value); }
    }
    public string TextBoxText
    {
        get { return (string)GetValue(TextBoxTextProperty); }
        set { SetValue(TextBoxTextProperty, value); }
    }
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        private set { SetValue(NameProperty, value); }
    }
    private static void OnComboBoxTextChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Person person = (Person)d;
        string value = (string)e.NewValue;
            person.Name = person.IsOtherSelected ? person.TextBoxText : value;
    }
    private static void OnTextBoxTextChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Person person = (Person)d;
        string value = (string)e.NewValue;
            person.Name = person.IsOtherSelected ? value : person.ComboBoxText;
    }
}
Notes:
- As in Bizz's answer, I've bound the derived property (in this case, Name) to aTextBlockjust so it's easy to see updates in the UI. You may or may not need to do something like this in your real-world code.
- The foundation for this approach is a DependencyObjectsubclass that serves as the actual target for the binding (i.e. theDataContextvalue). You can either set your program up so that this is in fact the data object for your code-behind logic, or (as in the MVVM pattern) a go-between that handles binding tasks for your actual data object. The important thing is that it's aDependencyObjectso that it can be used directly in the binding syntax in XAML (implementingINotifyPropertyChangedshould work as well).
- Instead of setting the DataContextin the code-behind, it is set here in the XAML. IMHO, if something can be handled in the XAML instead of the code-behind it is better to do so. This allows the XAML editor and compiler to know more about the implementation details and provide better feedback, in the form of Intellisense or a compile-time error as appropriate.
- The part that takes care of mapping the appropriate UI selection to your Nameproperty are thePropertyChangedCallbackmethods,OnComboBoxTextChanged()andOnTextBoxTextChanged(). When theDependencyPropertyvalues for these properties are registered, these callback methods are provided for the properties and are called any time the values of the properties change. Each updates theNameproperty according to the current value of theIsOtherSelectedproperty (which itself is automatically kept up-to-date by the binding system, it having been bound to theIsSelectedproperty of the last item in yourComboBox).
- Note that there's not actually any need to respond to changes in the IsOtherSelectedproperty. We know that property will change only if theSelectedValueproperty changes, and changes to that property will already update theNameproperty value.
- One of the things your original code was doing was setting the Visibilityof theTextBoxtoCollapsedunless the "Other" value was selected in theComboBox. This is effected here by setting up aDataTriggerin theStylefor theTextBox. The defaultVisibilityisVisible, and it stays that way as long as the trigger isn't triggered. But if it is triggered, i.e. theIsOtherSelectedproperty becomesfalse, theSetterin theDataTriggerwill be applied, setting theVisibilityvalue toCollapsedas desired. If and when the trigger is no longer satisfied, WPF sets the property value back to its previous value (i.e.Visible).
IMHO it is worth taking the time to understand this approach. I understand (having been through this recently and in fact continuing to go through it myself) that learning the XAML/binding-based philosophy of WPF is daunting. There are often many different ways to do things in WPF and it's not always clear which is the best way. At the same time, it is harder to detect and understand errors in the XAML (hint: check the run-time output for the program in the debugger's "Output" window). But the binding system can handle a lot of the presentation scenarios that come up in a GUI-based program, and in many cases all of the scenarios in a given program. Working with the API is in the long run a lot easier, even if much harder at the outset. :)
Finally, I'll share a second way to accomplish the same thing. Instead of handling the mapping in your DependencyObject subclass itself (i.e. through separate bound properties in the subclass which are mapped to a third property), you can create a MultiBinding object with a custom converter that knows how to integrate two or more input values to produce a single output value.
Unfortunately, I wasn't able to figure out how to configure this in the XAML (did I mention I'm still learning it myself? :) ), but the code-behind is not complicated. If there is a way to get it set up in the XAML, it will look very similar: a MultiBinding object goes in place of a Binding, the Converter property is set for it, and the multiple Binding objects are added to the MultiBinding object as children. This in fact does often work normally; I think there's just something about trying to bind to DataContext object rather than a FrameworkElement subclass that I haven't figured out yet.
Anyway, the code looks like this:
XAML:
<Window x:Class="MultiBindingVersion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MultiBindingVersion"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <local:ComboAndTextToTextConverter x:Key="comboAndTextToTextConverter1"/>
  </Window.Resources>
  <StackPanel x:Name="spTest">
    <StackPanel.DataContext>
      <local:Person/>
    </StackPanel.DataContext>
    <ComboBox x:Name="cmbTest" Width="140" Margin="5" SelectedValuePath="Content">
      <ComboBoxItem Content="Name1"/>
      <ComboBoxItem Content="Name2"/>
      <ComboBoxItem Content="Name3"/>
      <ComboBoxItem Content="Name4"/>
      <ComboBoxItem x:Name="otherItem" Content="Other"/>
    </ComboBox>
    <TextBox x:Name="txtTest"  Width="140" Margin="5">
      <TextBox.Style>
        <Style TargetType="TextBox">
          <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=otherItem, Path=IsSelected}"
                         Value="False">
              <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
          </Style.Triggers>
        </Style>
      </TextBox.Style>
    </TextBox>
    <TextBlock x:Name="textBlock1" Text="{Binding Path=Name}"/>
  </StackPanel>
</Window>
C#:
public class Person : DependencyObject
{
    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(Person));
    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
}
class ComboAndTextToTextConverter : IMultiValueConverter
{
    public object Convert(object[] values,
        Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string comboBoxText = values[1] as string;
        string textBoxText = values[2] as string;
        if (values[0] is bool && comboBoxText != null && textBoxText != null)
        {
            bool otherItemIsSelected = (bool)values[0];
            return otherItemIsSelected ? textBoxText : comboBoxText;
        }
        return Binding.DoNothing;
    }
    public object[] ConvertBack(object value,
        Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        _SetMultibinding((Person)spTest.DataContext, Person.NameProperty,
            Tuple.Create((DependencyObject)otherItem, ComboBoxItem.IsSelectedProperty),
            Tuple.Create((DependencyObject)cmbTest, ComboBox.SelectedValueProperty),
            Tuple.Create((DependencyObject)txtTest, TextBox.TextProperty));
    }
    private void _SetMultibinding(DependencyObject target,
        DependencyProperty property,
        params Tuple<DependencyObject, DependencyProperty>[] properties)
    {
        MultiBinding multiBinding = new MultiBinding();
        multiBinding.Converter =
            (IMultiValueConverter)Resources["comboAndTextToTextConverter1"];
        foreach (var sourceProperty in properties)
        {
            Binding bindingT = new Binding();
            bindingT.Source = sourceProperty.Item1;
            bindingT.Path = new PropertyPath(sourceProperty.Item2);
            multiBinding.Bindings.Add(bindingT);
        }
        BindingOperations.SetBinding(target, property, multiBinding);
    }
}
Note:
- In this case, the Personobject has only theNameproperty needed, with just the basicDependencyPropertyimplementation. In the other example, thePersonobject exists as the source for the bound properties (even though logically it's the target). But with theMultiBinding, the target really does need to be the target. Since the binding will be specified in code-behind, the XAML doesn't have any bindings declared (except the visibility trigger), and thePersonobject thus doesn't need those individual properties to which the XAML elements can be bound.
- There's a new class here, ComboAndTextToTextConverter. This is the class that will accept the multiple inputs and convert them to a single output. You can see reading the code that it takes three values as input: abool, and twostringvalues (theComboBox.SelectedValueandTextBox.Textproperty values, respectively). The code does some minimal validation on the types and then maps the values as appropriate.
- The window's code-behind is where the MultiBindingis created and set. I have a simple helper method that takes the target object and property, and a variable number of source objects and properties. It simply loops through the sources, adding them to theMultiBindingobject, and then setting thatMultiBindingobject on the target object's property.
- Since the Personobject no longer has the helper properties, including theIsOtherSelectedproperty, I went ahead and named the lastComboBoxitem so that it can be bound by name in the trigger for theTextBox'sVisibilityproperty.
- I used the converter from the window's resources, but you could as easily not bother putting the converter into the resources and just create a new instance, i.e. new ComboAndTextToTextConverter(). Mostly my choice here is an artifact of my earlier attempts to get theMultiBindingconfigured via XAML (where the converter would need to be declared as a resource).
Sorry for the lengthy answer. I wanted to try to explain everything with reasonable detail, i.e. the sort of detail I wished I'd had when I was trying to figure this stuff out myself. :) I hope it helps!