使用转换器将窗口标题绑定到属性
我试图绑定窗口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();
}
}
}
如果移动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();
}
}
这使得它来编译,但它引发的启动异常。 '附加信息:'匹配指定绑定约束的类型'WpfApplication1.MainWindow'上构造函数的调用引发异常。'行号'4'和行位置'9'。' 我不太确定该怎么做。 – 2011-03-24 21:05:52
@Rob W .:你确定与'Title'绑定有关吗?如果删除它,问题是否消失? – 2011-03-24 21:22:12
@Rob W .:我试过你的代码,问题是布尔DP修改的默认值。更新我的回答 – 2011-03-24 21:29:40
你实际上并不说明有什么不工作... – 2011-03-24 21:37:54