首页 > 解决方案 > 调用事件 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();
        }
    }

标签: c#wpfdata-binding

解决方案


我认为你让它变得非常复杂。

首先,在顶部窗口元素的 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 是


推荐阅读