使用转换器将窗口标题绑定到属性

使用转换器将窗口标题绑定到属性

问题描述:

我试图绑定窗口Title属性,以便它将显示对象的文件名和修改后的状态。文件名和修改状态都是对象上的依赖项属性。使用转换器将窗口标题绑定到属性

我知道我可能只是添加一个“WindowTitle”属性或对象,但似乎相当hacky。我创建了一个我想要做的非常简洁的版本。

这里的XAML:

<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" 
    Title="{Binding Converter={StaticResource windowTitleConverter}}" Height="195" Width="245"> 
<Window.Resources> 
    <local:WindowTitleConverter x:Key="windowTitleConverter"/> 
</Window.Resources> 
<Grid Height="150" Width="217"> 
    <TextBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding FileName}" /> 
    <CheckBox Content="Modified" Height="16" HorizontalAlignment="Left" Margin="12,41,0,0" Name="checkBox1" VerticalAlignment="Top" IsChecked="{Binding Modified}" /> 
</Grid> 

,代码:

using System; 
using System.Globalization; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new Foo(); 
     } 
    } 

    public class Foo : DependencyObject 
    { 
     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()); 

     public bool Modified 
     { 
      get { return (bool)GetValue(ModifiedProperty); } 
      set { SetValue(ModifiedProperty, value); } 
     } 

     public static readonly DependencyProperty ModifiedProperty = 
      DependencyProperty.Register("Modified", typeof(bool), typeof(Foo), new UIPropertyMetadata(0)); 
    } 

    public class WindowTitleConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      Foo foo = (Foo)value; 
      if (foo == null || foo.FileName == null) 
       return "Foo"; 
      return foo.FileName + (foo.Modified ? " *" : ""); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 
    } 
} 
+0

你实际上并不说明有什么不工作... – 2011-03-24 21:37:54

如果移动Title资源,将工作结合以下。我不知道为什么,声明的顺序是非常重要的在这里,但它是,似乎是一个错误给我

<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> 

更新

你现在得到的问题是因为依赖属性修改了错误的默认值类型。这是布尔类型,并且将其设置为0,将其更改为假,它应该工作

public static readonly DependencyProperty ModifiedProperty = 
    DependencyProperty.Register("Modified", 
           typeof(bool), 
           typeof(Foo), 
           new UIPropertyMetadata(false)); 

更新

我不知道任何方式直接绑定到何时提出PropertyChanged DataContext的。你可以使用一个小的解决方法是绑定到一个名为此属性,它只是返回this

<Window.Title> 
    <Binding Path="This" Converter="{StaticResource windowTitleConverter}"/> 
</Window.Title> 

然后你可以使用PropertyChangedCallback提高PropertyChanged为这

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)); 
     } 
    } 
} 

另一种解决办法是使用MultiBinding代替其将消除需要在此属性

<Window.Resources> 
    <local:TitleMultiConverter x:Key="TitleMultiConverter"/> 
</Window.Resources> 
<Window.Title> 
    <MultiBinding Converter="{StaticResource TitleMultiConverter}"> 
     <Binding Path="FileName"/> 
     <Binding Path="Modified"/> 
    </MultiBinding> 
</Window.Title> 

山雀leMultiConverter

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(); 
    } 
} 
+0

这使得它来编译,但它引发的启动异常。 '附加信息:'匹配指定绑定约束的类型'WpfApplication1.MainWindow'上构造函数的调用引发异常。'行号'4'和行位置'9'。' 我不太确定该怎么做。 – 2011-03-24 21:05:52

+0

@Rob W .:你确定与'Title'绑定有关吗?如果删除它,问题是否消失? – 2011-03-24 21:22:12

+0

@Rob W .:我试过你的代码,问题是布尔DP修改的默认值。更新我的回答 – 2011-03-24 21:29:40