If you move the Title binding below Resources, it will work. I'm not sure why the order of the ads matters here, but this seems to be a mistake for me
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Height="195" Width="245"> <Window.Resources> <local:WindowTitleConverter x:Key="windowTitleConverter"/> </Window.Resources> <Window.Title> <Binding Converter="{StaticResource windowTitleConverter}"/> </Window.Title> </Window>
Update
The problem you are currently facing is that the modified dependency property has the wrong default value type. This is a bool type, and you set it to 0 to change it to false, and it should work
public static readonly DependencyProperty ModifiedProperty = DependencyProperty.Register("Modified", typeof(bool), typeof(Foo), new UIPropertyMetadata(false));
Update
I don't know how to enhance PropertyChanged when binding directly to a DataContext. A small workaround you can use is to bind to the "This" property, which simply returns this
<Window.Title> <Binding Path="This" Converter="{StaticResource windowTitleConverter}"/> </Window.Title>
Then you can use PropertyChangedCallback to raise PropertyChanged for this
public class Foo : DependencyObject, INotifyPropertyChanged { public Object This { get { return this; } } public bool Modified { get { return (bool)GetValue(ModifiedProperty); } set { SetValue(ModifiedProperty, value); } } public string FileName { get { return (string)GetValue(FileNameProperty); } set { SetValue(FileNameProperty, value); } } public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register("FileName", typeof(string), typeof(Foo), new UIPropertyMetadata(string.Empty, new PropertyChangedCallback(OnFileNameChanged))); public static readonly DependencyProperty ModifiedProperty = DependencyProperty.Register("Modified", typeof(bool), typeof(Foo), new UIPropertyMetadata(false, new PropertyChangedCallback(OnModifiedChanged))); private static void OnFileNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { Foo foo = obj as Foo; foo.OnPropertyChanged("This"); } private static void OnModifiedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { Foo foo = obj as Foo; foo.OnPropertyChanged("This"); } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
Another solution would be to use MultiBinding instead, which will eliminate the need for this property.
<Window.Resources> <local:TitleMultiConverter x:Key="TitleMultiConverter"/> </Window.Resources> <Window.Title> <MultiBinding Converter="{StaticResource TitleMultiConverter}"> <Binding Path="FileName"/> <Binding Path="Modified"/> </MultiBinding> </Window.Title>
TitleMultiConverter
public class TitleMultiConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { string fileName = values[0].ToString(); bool modified = (bool)values[1]; if (fileName == null) return "Foo"; return fileName + (modified ? " *" : ""); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }