gpt4 book ai didi

c# - 使用转换器将窗口标题绑定(bind)到属性

转载 作者:太空狗 更新时间:2023-10-29 20:00:31 25 4
gpt4 key购买 nike

我正在尝试绑定(bind)窗口 Title 属性,以便它显示对象的文件名和修改状态。文件名和修改状态都是对象的依赖属性。

我知道我可能只向对象添加一个“WindowTitle”属性或类似属性,但这看起来很老套。我已经创建了一个我正在尝试做的非常精简的版本。

这是 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 绑定(bind)移动到资源下方,它将起作用。我不确定为什么声明的顺序在这里很重要,但它对我来说似乎是一个错误

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

更新

您现在遇到的问题是因为 Dependency Property Modified 具有错误的默认值类型。它是 bool 类型,你将它设置为 0,所以将它更改为 false,它应该可以工作

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

更新

我不知道有什么方法可以在直接绑定(bind)到 DataContext 时引发 PropertyChanged。您可以使用的一个小解决方法是绑定(bind)到一个名为 This 的属性,它只返回 this

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

然后您可以使用 PropertyChangedCallback 为 This 引发 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 代替,这将消除对 This 属性的需求

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

关于c# - 使用转换器将窗口标题绑定(bind)到属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5422635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com