Search code examples
c#wpfvisual-studioxamlresharper

Refactoring property name in code behind does not propagate to XAML file


I'm trying to refactor the property MyText to a new name HerText in the following solution:

MainWindow.xaml.cs

using System.Windows;

namespace resharper_refactoring_xaml
{
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
      public MainWindow()
      {
         InitializeComponent();
         MyText = "Blabla";
         DataContext = this;
      }

      public string MyText { get; set; }
   }
}

MainWindow.Xaml

<Window x:Class="resharper_refactoring_xaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:resharper_refactoring_xaml"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
   <Grid>
      <TextBlock Text="{Binding Path=MyText}"></TextBlock>
   </Grid>
</Window>

I right click on the property and select Refactor this > Rename. Then I type in a new name for the property, hit Next.

Unfortunately, only the references of MyText in the code-behind are renamed. References to MyText in the XAML file rename intact.

According to this question Resharper should be able to propagate refactorings to XAML files.

Why is the rename not propagating to the XAML file? Is there some sort of Resharper setting I might have overlooked?


Solution

  • The reason behind this seems to be that ReSharper cannot determine that the property name specified in the XAML markup refers to the property defined in the MainWindow class, if the DataContext property is set in code-behind. Bindings refer to the DataContext of controls as source by default. If it is not detected, the link between the loose markup and the defining type is lost. I cannot tell if this is a bug in ReSharper or a general limitation.

    However, there are two simple solutions to this issue that work for me:

    1. Set a design time data context to the type that defines the property here MainWindow.

      <Window ...
              d:DataContext="{d:DesignInstance Type={x:Type local:MainWindow}}">
      
    2. Set the data context via binding in XAML instead of code-behind.

      <Window ...
              DataContext="{Binding RelativeSource={RelativeSource Self}}">