не выполняется повторная привязка при изменении свойств события вызова - PullRequest
1 голос
/ 29 мая 2020

У меня есть 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
            }
        }
    }
}

final вот класс 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();
        }
    }

1 Ответ

0 голосов
/ 30 мая 2020

Я думаю, вы делаете это очень сложным.

Сначала установите имя в 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}"/>

Затем просто создайте свойство в своей CategoryAddFoodForm типа ImageSource:

public ImageSource CategoryImage { set; get; }

И установите значение из ваше диалоговое окно напрямую к этому свойству вместо использования вашего класса конвертера:

<ImageBrush Stretch="Uniform" ImageSource="{Binding ElementName=CategoryAddFoodFormWindow, Path=CategoryImage/>

INotifyPropertyChanged не требуется, а класс ConvertImage имеет значение

...