简而言之,我想创建一个可更新的列表框,它将在从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)。
不管是什么原因,我相信它是隐藏在错误的背后与阅读名单。
1条答案
按热度按时间bd1hkmkf1#
错误消息的来源是绑定表达式
虽然有一个从
string
,Uri
和byte[]
到ImageSource
(Source
属性的类型)的内置自动类型转换,但没有自动转换回TwoWay
绑定所需的那些类型(除了字符串)。Source
属性的TwoWay
绑定首先是毫无意义的,因为Image元素本身永远不会更改该属性。这同样适用于TextBlock元素的Text
属性绑定。因此,只需使用
OneWay
绑定,其中设置UpdateSourceTrigger
也没有意义,因为它只影响TwoWay
和OneWayToSource
绑定。此外,
ItemsSource
绑定的source属性必须是实现INotifyPropertyChanged
接口的集合,例如一个ObservableCollection而不是List:属性也应该是只读的:
绑定也不是双向的,但应该是
因为ListBox从不主动更改其
ItemsSource
属性的值。这并不意味着属性引用的集合不能更改。