wpf 列表框拒绝更新/列表没有匹配的类型

ej83mcc0  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(96)

简而言之,我想创建一个可更新的列表框,它将在从ComboBox中选择一个选项时更新

<ListBox Background="Transparent" Width="Auto" Height="Auto" HorizontalAlignment="Right" ScrollViewer.CanContentScroll="true" ItemsSource="{Binding Lessons, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <WrapPanel>
                                <TextBlock Text="{Binding LessonText, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
                                    <StackPanel>
                                        
                                     </StackPanel>
                                </TextBlock>
                                <Image Source="{Binding LessonImage, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" HorizontalAlignment="Center" Width="auto" MaxWidth="400"/>
                            </WrapPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

更改变量的值Lesson将触发一个操作,该操作将使用元素填充对象列表

public class LessonData : BaseViewModel
  {
    public int _lessonID;
    public string _lessonText;
    public byte[] _lessonImage;

    public int LessonID { get { return _lessonID; } set { _lessonID = value; OnPropertyChanged(nameof(LessonID)); } }
    public string LessonText { get { return _lessonText; } set { _lessonText = value; OnPropertyChanged(nameof(LessonText)); } }
    public byte[] LessonImage { get { return _lessonImage; } set { _lessonImage = value; OnPropertyChanged(nameof(LessonImage)); } }
  }
public List<LessonData> editedLessons = new List<LessonData>();

 public List<LessonData> EditedLessons { get { return editedLessons; } set { editedLessons = value; OnPropertyChanged(nameof(EditedLessons)); } }

 public string Lesson { get { return _lesson; } set { _lesson = value; OnPropertyChanged(nameof(Lesson));
        if (Lesson == "None")
        {
          EditedLessons.Clear();
          IsLessonBeingEdited = false;
        }
        else
        {
          EditedLessons = lessonRepository.Obtain_Lesson_Content(Lesson);
          foreach (LessonData p in EditedLessons) { Console.WriteLine(p.LessonID, p.LessonText, p.LessonImage); }
          IsLessonBeingEdited = true;
        }
      } }

下面是来自存储库的函数

public List<LessonData> Obtain_Lesson_Content(string Lesson)
    {
      List<LessonData> lc = new List<LessonData>();
      using (var connection = GetConnection())
      using (var command = new SqlCommand())
      {
        connection.Open();
        command.Connection = connection;
        command.CommandText = "SELECT Id_Lesson_Content, Lesson_Text, Lesson_Image FROM [Lesson_Content] WHERE Id_Lesson_Title = (SELECT Id_Lesson FROM [Lesson_Title] WHERE Lesson_Title = @title)";
        command.Parameters.Add("@title", SqlDbType.NVarChar).Value = Lesson;
        using (var reader = command.ExecuteReader())
        {
          while (reader.Read())
          {
            LessonData model = new LessonData();
            model.LessonID = (int)reader["Id_Lesson_Content"];
            model.LessonText = reader["Lesson_Text"].ToString();
            if (reader["Lesson_Image"] != System.DBNull.Value)
              model.LessonImage = (byte[])reader["Lesson_Image"];
            else
              model.LessonImage = null;
            lc.Add(model);
          }
          reader.NextResult();
        }
        foreach (LessonData p in lc) { Console.WriteLine(p.LessonID, p.LessonText, p.LessonImage); }
        return lc;
      }
    }

然而,每次我调用这个函数时,我都会遇到抛出的错误(在这种情况下,它加载了两个对象,一个有图像,一个没有图像):

System.Windows.Data Error: 1 : Cannot create default converter to perform 'two-way' conversions between types 'System.Byte[]' and 'System.Windows.Media.ImageSource'. Consider using Converter property of Binding. BindingExpression:Path=LessonImage; DataItem='LessonData' (HashCode=2419756); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='System.Byte[]' BindingExpression:Path=LessonImage; DataItem='LessonData' (HashCode=2419756); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
System.Windows.Data Error: 1 : Cannot create default converter to perform 'two-way' conversions between types 'System.Byte[]' and 'System.Windows.Media.ImageSource'. Consider using Converter property of Binding. BindingExpression:Path=LessonImage; DataItem='LessonData' (HashCode=10026414); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')

但对我来说,最奇怪的部分是,试图在控制台中编写所有列表对象会引发以下三个错误:

  • 无法从int转换为char[],
  • 从string到int
  • 从byte[]到int

foreach(LessonData p in lc){ Console.WriteLine(p.LessonID,p.LessonText,p.LessonImage);}
为什么会这样我已经看过我的其他相同/类似的功能,以同样的方式工作,他们都没有抛出这样的编译错误。最重要的是,当我通过将LessonID作为最后一个来更改对象元素的顺序时,它不会显示错误,(但是唯一显示的项目是LessonText)。
不管是什么原因,我相信它是隐藏在错误的背后与阅读名单。

bd1hkmkf

bd1hkmkf1#

错误消息的来源是绑定表达式

Source="{Binding LessonImage, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

虽然有一个从stringUribyte[]ImageSourceSource属性的类型)的内置自动类型转换,但没有自动转换回TwoWay绑定所需的那些类型(除了字符串)。
Source属性的TwoWay绑定首先是毫无意义的,因为Image元素本身永远不会更改该属性。这同样适用于TextBlock元素的Text属性绑定。
因此,只需使用OneWay绑定,其中设置UpdateSourceTrigger也没有意义,因为它只影响TwoWayOneWayToSource绑定。

Source="{Binding LessonImage}"

此外,ItemsSource绑定的source属性必须是实现INotifyPropertyChanged接口的集合,例如一个ObservableCollection而不是List:
属性也应该是只读的:

public ObservableCollection<LessonData> EditedLessons { get; }
    = new ObservableCollection<Lesson>();

绑定也不是双向的,但应该是

<ListBox ItemsSource="{Binding EditedLessons}" ...>

因为ListBox从不主动更改其ItemsSource属性的值。这并不意味着属性引用的集合不能更改。

相关问题