При попытке использовать в отдельном потоке вылетает ошибка System.Windows.Markup.XamlParseException: ""Задание свойства "System.Windows.Controls.Image.Source" вызвало исключение.": номер строки "25" и позиция в строке "13"." Причем если обновление данных в textbox, то все работает нормально, а если в image, то вылетает указанная ошибка.
Exeption: InnerException {"Необходимо создать DependencySource в том же потоке, в котором создан DependencyObject."} System.Exception {System.ArgumentException}
Stack Trace:
StackTrace " в System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)\r\n в System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)\r\n в System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)\r\n в System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)\r\n в VideoMessager.MainWindow.InitializeComponent() в C:\\Users\\Medhelp\\source\\repos\\VideoMessager\\VideoMessager\\MainWindow.xaml:строка 1" string
Model, которая с текстом и работает
class TestText : INotifyPropertyChanged
{
public void UpdateText(Action<string> action)
{
for (int i = 0; i < 100; i++)
{
action(i.ToString());
Thread.Sleep(500);
}
}
public void UpdateFrame(Action<BitmapSource> updateDelegate)
{
while (true)
{
string name = Assembly.GetEntryAssembly().GetName().Name;
for (int i = 0; i < 29; i++)
{
BitmapImage image = new BitmapImage(new Uri(@"pack://application:,,,/" + name + ";Component/Img/frame_" + i.ToString() + "_delay-0.08s.gif"));
updateDelegate(image);
Thread.Sleep(50);
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using VideoMessager.Models;
using System.Windows.Media.Imaging;
using System.Net;
using System.Windows.Controls;
namespace VideoMessager.ViewModels
{
public delegate void UpdateImagesDelegate(BitmapImage image);
class Main : INotifyPropertyChanged
{
private VideoCall video;
public VideoCall Video
{
get
{
return video;
}
set
{
video = value;
OnPropertyChanged("Video");
}
}
private BitmapSource imageFrame;
public BitmapSource ImageFrame
{
get
{
return imageFrame;
}
set
{
imageFrame = value;
OnPropertyChanged("ImageFrame");
}
}
private string testText;
public string TestText
{
get
{
return testText;
}
set
{
testText = value;
OnPropertyChanged("TestText");
}
}
public TestText test = new TestText();
public Main()
{
Video = new VideoCall(IPAddress.Parse("127.0.0.1"), 5600);
var UpdateFrame = Task.Run(() =>
{
test.UpdateText(UpdateUI);
test.UpdateFrame(UpdateImage);
});
}
public void UpdateImage(BitmapSource image)
{
ImageFrame = image;
}
public void UpdateUI(string s)
{
TestText = s;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
View
<Window
x:Class="VideoMessager.MainWindow"
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:local="clr-namespace:VideoMessager"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModel="clr-namespace:VideoMessager.ViewModels"
Title="Main"
Width="300"
Height="300"
mc:Ignorable="d">
<Window.DataContext>
<viewModel:Main />
</Window.DataContext>
<Grid>
<Image
Width="272"
Height="212"
Margin="10,26,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="{Binding Path=ImageFrame, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<Button
Width="134"
Margin="148,243,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Выбрать" />
<Button
Width="133"
Margin="10,243,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Отправить" />
<TextBox
Width="120"
Height="23"
Margin="106,35,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Text="{Binding Path=TestText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
TextWrapping="Wrap" />
</Grid>
</Window>
View, а не в модели и не в вьюмодели. 2) обновление изображений и текста через равные промежутки времени лучше всего производить с помощью анимации, логика которой пишется прямо вXAML.