c# - 调用事件 Propertieschanged 时不重新绑定
问题描述
我的Ellipse
应用程序中有一个ImageBrush
. 当我ImageBrush.ImageSource
单击Ellipse
. 我正在使用ConvertImage
实现IValueConverter
数据转换的类。但是当我更改数据并调用函数 PropertiesChanged 时,它不会调用类ConvertImage
并且不会提醒数据。
这是我的代码 Xaml:
<Window x:Class="CoffeeManager.Controls.CategoryControl.CategoryAddFoodForm"
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:CoffeeManager.Controls.CategoryControl"
xmlns:coffeeManager="clr-namespace:CoffeeManager"
xmlns:foodView="clr-namespace:CoffeeManager.Controls.FoodControl"
mc:Ignorable="d"
Style="{StaticResource WindowStyle}"
Title="Add Food To Categoory" Height="600" Width="1000" Background="#1e1e1e" Loaded="CategoryAddFoodForm_OnLoaded">
<Grid>
<Grid.Resources>
<coffeeManager:ConvertImage x:Key="ConvertImage"/>
</Grid.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="1" Margin="10" StrokeThickness="2" Stroke="White" MouseDown="UIElement_OnMouseDown">
<Ellipse.Fill>
<ImageBrush Stretch="Uniform" ImageSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:CategoryViewForm}}, Path=Category.Image, Converter={StaticResource ConvertImage}, UpdateSourceTrigger=PropertyChanged}"/>
</Ellipse.Fill>
</Ellipse>
</Grid>
</Grid>
</Window>
这是后面的代码:
namespace CoffeeManager.Controls.CategoryControl
{
/// <summary>
/// Interaction logic for CategoryAddFoodForm.xaml
/// </summary>
public partial class CategoryAddFoodForm : Window, INotifyPropertyChanged
{
private Category category;
public Category Category
{
get => category;
set
{
category = value;
OnPropertiesChanged("Category");
}
}
public CategoryAddFoodForm()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertiesChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var of = new OpenFileDialog
{
Filter = StaticValue.FilterImage
};
if (of.ShowDialog() == true)
{
if (!Directory.Exists(Environment.CurrentDirectory + StaticValue.PathDirectoryCategory)) Directory.CreateDirectory(Environment.CurrentDirectory + StaticValue.PathDirectoryCategory);
if (string.IsNullOrEmpty(category.Image) || !category.Image.Contains(StaticValue.OtherCode))
{
File.Copy(of.FileName, Environment.CurrentDirectory + StaticValue.PathDirectoryCategory + category.Name + StaticValue.CategoryExtensions, true);
category.Image = StaticValue.PathDirectoryCategory + category.Name + StaticValue.CategoryExtensions;
}
else
{
File.Copy(of.FileName, Environment.CurrentDirectory + StaticValue.PathDirectoryCategory + category.Name + StaticValue.OtherCode + StaticValue.CategoryExtensions, true);
category.Image = StaticValue.PathDirectoryCategory + category.Name + StaticValue.OtherCode + StaticValue.CategoryExtensions;
}
OnPropertiesChanged("Category"); //when I call Propertieschanged here it do nothing
}
}
}
}
最后是 ConvertImage 类:
public class ConvertImage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
if (string.IsNullOrEmpty(value.ToString()))
{
return null;
}
try
{
return new BitmapImage(new Uri(Environment.CurrentDirectory + value.ToString()));
}
catch { }
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return string.Empty;
string[] elementUri = value.ToString().Split('/');
bool isReSources = false;
StringBuilder resulf = new StringBuilder();
foreach (string s in elementUri)
{
if (s == "Resources")
{
isReSources = true;
}
if (isReSources)
{
resulf.Append(@"\" + s);
}
}
return resulf.ToString();
}
}
解决方案
我认为你让它变得非常复杂。
首先,在顶部窗口元素的 Xaml 中设置一个名称 - 例如 CategoryAddFoodFormWindow:
<Window x:Class="CoffeeManager.Controls.CategoryControl.CategoryAddFoodForm" ... x:Name="CategoryAddFoodFormWindow">
然后,通过以下方式绑定到 CategoryAddFoodForm 类中的属性要容易得多:
<ImageBrush Stretch="Uniform" ImageSource="{Binding ElementName=CategoryAddFoodFormWindow, Path=Category.Image, Converter={StaticResource ConvertImage}, UpdateSourceTrigger=PropertyChanged}"/>
接下来,只需在 ImageSource 类型的 CategoryAddFoodForm 上创建一个属性:
public ImageSource CategoryImage { set; get; }
并将对话框中的值直接设置为该属性,而不是使用转换器类:
<ImageBrush Stretch="Uniform" ImageSource="{Binding ElementName=CategoryAddFoodFormWindow, Path=CategoryImage/>
INotifyPropertyChanged 不是必需的,并且类 ConvertImage 是
推荐阅读
- sql - SQL 计数不同的输出不是所希望的
- python - Inserting multiple values into a database
- javascript - 带有标题后退按钮的反应导航抽屉导航器
- sql-server - 如何找出同一张表中特定状态的多个计数
- python - Python 3,打包的字节顺序/字顺序输出问题
- python - 如何在python数据框中执行包含条件的字符串
- vb.net - 运行时控件大小不同
- android - NetworkBoundResource 连续调用
- angular - Angular - 是否使用标签或按钮
- javascript - 数组长度返回 0