[在WPF中,我试图使用在类中的属性来创建作为ItemsControl中ItemTemplate的一部分创建的按钮来选择样式。我以为自己编码正确,但是当我运行它时,它会创建“测试”按钮,但它甚至从未运行样式的转换器。
顺便说一句,是的,我显然知道我还没有正确实现IValueConverter,但是当我设置断点时,它甚至都没有进入转换器。
此外,当属性CurrentItemProperty的值更改时,如何正确保持按钮的样式更新?
MainWindow.xaml
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:ButtonStyleConverter x:Key="ButtonStyleConverter"/>
</Window.Resources>
<Grid>
<ItemsControl x:Name="ButtonList">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="OptionButton">
<Button Content="{Binding DisplayName}" Style="{Binding CurrentItem, Converter={StaticResource ButtonStyleConverter}}"></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
MainWindow.xaml.cs
namespace WpfApp1
{
public partial class MainWindow : Window
{
DependencyProperty CurrentItemProperty = DependencyProperty.Register("CurrentItemProperty", typeof(string), typeof(MainWindow));
public string CurrentItem
{
get
{
return (string)GetValue(CurrentItemProperty);
}
set
{
SetValue(CurrentItemProperty, value);
}
}
public MainWindow()
{
InitializeComponent();
ButtonList.ItemsSource = new OptionButton[]
{
new OptionButton() { DisplayName = "Test"}
};
CurrentItem = "Test";
}
public class OptionButton
{
public string DisplayName { get; set; }
}
}
public class ButtonStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
当我设置断点时,它甚至都不会进入转换器。
因为没有要转换的东西。
如果您要在调试器中运行代码并查看调试输出,则会发现出现绑定错误,绑定引擎无法在源对象上找到属性CurrentItem
。这是因为源对象是OptionButton
实例,它当然没有CurrentItem
属性。
您有许多可用的选项:
OptionButton
类型的属性。在您的示例中,CurrentItem
和OptionButton.DisplayName
具有相同的值,因此从字面上看,您可以直接绑定到DisplayName
属性。另外,也许您可以在OptionButton
中实现一个属性,该属性委派给您关心的父级值。CurrentItem
属性可见。 (至少)此主题有两个变体:为窗口提供name属性,并在绑定中通过名称引用它,或者仅使用{RelativeSource AncestorType=Window}
标记作为绑定的来源。最重要的是,该绑定无法正常工作,因为该绑定的当前数据上下文(定义了绑定的默认源)不具有您要绑定的属性。