Silverlight для Windows Embedded: как распространить значение пользовательского свойства из xaml во встроенное приложение проекта VS
Я работаю над проектом Silverlight для Windows Embedded. Я определил пользовательский элемент управления, который состоит из элемента управления TextBlock и элемента управления изображением. Я хочу указать другой текст в другом экземпляре пользовательского элемента управления. Итак, я сделал следующее в Expression Blend: В Blend code-behind (C#) UserControl1.xaml.cs я определил и зарегистрировал свойство DependencyProperty и установил DataContext для TextBlock:
namespace WindowsEmbeddedSilverlightApplication1
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
ItemText.DataContext = this;
}
public String MyText
{
get { return (String)GetValue(MyTextProperty); }
set { SetValue(MyTextProperty, value); }
}
public static readonly DependencyProperty MyTextProperty =
DependencyProperty.Register("MyText", typeof(String), typeof(UserControl1), null);
}
}
В UserControl1.xaml:
<UserControl
......
x:Class="WindowsEmbeddedSilverlightApplication1.UserControl1"
d:DesignWidth="196" d:DesignHeight="85">
<Grid x:Name="LayoutRoot">
<Image x:Name="ItemImage" Margin="0,0,90,0"/>
<TextBlock x:Name="ItemText" HorizontalAlignment="Right" Width="68" Text="{Binding MyText}" TextWrapping="Wrap" Height="23" VerticalAlignment="Bottom"/>
</Grid>
</UserControl>
Чтобы использовать пользовательский элемент управления в MainPage.xaml:
<UserControl
......
xmlns:local="clr-namespace:WindowsEmbeddedSilverlightApplication1"
x:Class="WindowsEmbeddedSilverlightApplication1.MainPage"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" Background="White">
<local:UserControl1 HorizontalAlignment="Left" Margin="94,117,0,0" Width="196" Height="85" VerticalAlignment="Top" MyText="Text1"/>
<local:UserControl1 HorizontalAlignment="Left" Margin="94,217,0,0" Width="196" Height="85" VerticalAlignment="Top" MyText="Text2"/>
</Grid>
</UserControl>
Таким образом, при запуске приложения в Expression Blend я могу видеть правильный текст, отображаемый на двух экземплярах пользовательского элемента управления.
Затем я импортирую проект в Visual Studio Silverlight для Windows Embedded Application. Я прочитал несколько сообщений, в которых упоминается, что я должен повторить регистрацию. Итак, я сделал следующее:
В UserControl1.h:
static HRESULT Register()
{
HRESULT hr = E_FAIL;
hr = XRCustomUserControlImpl<UserControl1>::Register (__uuidof(UserControl1), L"UserControl1", L"clr-namespace:WindowsEmbeddedSilverlightApplication1");
hr = RegisterDependencyProperties();
return hr;
}
static HRESULT RegisterDependencyProperties();
HRESULT SetMyText(WCHAR* pText);
HRESULT GetMyText(BSTR* pbstrText);
public:
static DEPENDENCY_PROPERTY_ID m_dpMyTextID;
В UserControl1.cpp:
HRESULT UserControl1::RegisterDependencyProperties()
{
HRESULT hr = E_FAIL;
IXRApplication* pApplication = NULL;
XRDependencyPropertyMetaData dpm = XRDependencyPropertyMetaData();
dpm.Size = sizeof(XRDependencyPropertyMetaData);
dpm.pfnPropertyChangeNotification = NULL;
dpm.pfnTypeConverter = NULL;
dpm.pfnEnumerableCreation = NULL;
XRValue defValue;
defValue.vType = VTYPE_READONLY_STRING;
defValue.pReadOnlyStringVal = L"Default";
dpm.DefaultValue = defValue;
hr = GetXRApplicationInstance(&pApplication);
hr = pApplication->RegisterDependencyProperty(L"MyText", VTYPE_BSTR, ControlID(), &dpm, &m_dpMyTextID);
pApplication->Release();
return hr;
}
HRESULT UserControl1::SetMyText( WCHAR* pText )
{
HRESULT hr = E_FAIL;
XRValue xrValue;
xrValue.vType = VTYPE_READONLY_STRING;
xrValue.pReadOnlyStringVal = pText;
hr = SetPropertyValue(m_dpMyTextID, &xrValue);
return hr;
}
HRESULT UserControl1::GetMyText( BSTR* pbstrText )
{
HRESULT hr = E_FAIL;
XRValue xrValue;
hr = GetPropertyValue(m_dpMyTextID, &xrValue);
if (SUCCEEDED(hr))
{
*pbstrText = xrValue.bstrStringVal;
}
return hr;
}
Я ничего не изменил в сгенерированном коде MainPage.h и MainPage.cpp.
Компиляция прошла успешно, и выполнение также в порядке. Пользовательские элементы управления отображаются, но тексты, которые я поместил в xaml, не отображаются.
Я делаю что-то не так или что-то упустил? Я не мог найти много информации на эту тему в Интернете. Может ли кто-нибудь указать мне в правильном направлении. Спасибо!
1 ответ
Задача решена.
Я добавил обратный вызов в XRDependencyPropertyMetaData.pfnPropertyChangeNotification:
dpm.pfnPropertyChangeNotification = NamePropertyChanged;
Согласно MSDN, PFN_PROPERTY_CHANGE - это метод обратного вызова, который XAML для Windows Embedded вызывает при изменении значения связанного свойства. Действительно, этот обратный вызов вызывается во время инициализации. В обратном вызове я установил для текста TextBlock новое значение:
void UserControl1::NamePropertyChanged(__in IXRDependencyObject* pControl, __in XRValue* pOldValue, __in XRValue* pNewValue)
{
HRESULT hr;
if (pControl && pOldValue && pNewValue)
{
UserControl1 *tempObj;
pControl->QueryInterface(__uuidof(UserControl1), (void**)&tempObj);
hr = tempObj->m_pItemText->SetText(pNewValue->pReadOnlyStringVal);
}
}
Таким образом, способ привязки значения DependencyProperty к элементу управления в выделенном коде C++ отличается от выделенного кода C#.