如何在ImageSource
的自定義wpf控件上實現DependencyProperty
?如何在ImageSource的自定義wpf控件上實現DependencyProperty?
我創建了一個自定義控件(按鈕),其中包括顯示圖像。我希望能夠從控件的外部爲圖像設置ImageSource,所以我實現了一個DependencyProperty。每當我嘗試更改ImageSource時,我都會收到一個SystemInvalidOperationException
:「調用線程無法訪問此對象,因爲不同的線程擁有它。」
好吧,所以主線程無法訪問圖像控件,所以我需要使用Dispatcher - 但是在哪裏以及如何?顯然,拋出異常在設定器,執行SetValue(ImageProperty, value);
tv_CallStart.xaml:
<Button x:Class="EHS_TAPI_Client.Controls.tv_CallStart" x:Name="CallButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="24" d:DesignWidth="24" Padding="0" BorderThickness="0"
Background="#00000000" BorderBrush="#FF2467FF" UseLayoutRounding="True">
<Image x:Name="myImage"
Source="{Binding ElementName=CallButton, Path=CallImage}" />
</Button>
tv_CallStart.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace EHS_TAPI_Client.Controls
{
public partial class InitiateCallButton : Button
{
public ImageSource CallImage
{
get { return (ImageSource)GetValue(CallImageProperty); }
set { SetValue(CallImageProperty, value); }
}
public static readonly DependencyProperty CallImageProperty =
DependencyProperty.Register("CallImage", typeof(ImageSource), typeof(InitiateCallButton), new UIPropertyMetadata(null));
public InitiateCallButton()
{
InitializeComponent();
}
}
}
設定從UI-的代碼隱藏圖像線程:
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("pack://application:,,,/EHS-TAPI-Client;component/Images/call-start.png");
bi.EndInit();
bi.Freeze();
CallButton.CallImage = bi;
和MainWindow.xaml其中控件初始化lised:
<ctl:InitiateCallButton x:Name="CallButton" CallImage="/Images/call-start.png" />
改編上面的源代碼,以反映我的進步..
解決方案:
上面的代碼發佈工作正常。最初版本的重要變化是添加了UI線程中的Freeze()方法(請參閱接受的答案)。 我的項目中的實際問題不是按鈕不是在UI線程中被初始化,但是新圖像是從另一個線程設置的。該圖像設置在一個事件處理程序中,該程序本身由另一個線程觸發。我使用Dispatcher
解決了這個問題:
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("pack://application:,,,/EHS-TAPI-Client;component/Images/call-start.png");
bi.EndInit();
bi.Freeze();
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
{
CallButton.CallImage = bi;
});
}
else
{
CallButton.CallImage = bi;
}
wth class names? –
你是對的,我很慚愧。特別是我傾向於遵循最佳實踐和命名慣例。這些課程是前一段時間創建的,我甚至不記得爲什麼我這次沒有正確地命名它們。這實際上使事情更糟糕o。O –
至少你似乎沒有混合德語,它可能更糟糕:P –