Я пытаюсь выполнить двустороннее связывание данных внутри UserControl
.Приведенный ниже код работает для одностороннего связывания, но когда я пытаюсь использовать двухстороннее связывание, я получаю следующую ошибку от компилятора xaml:
XamlCompiler error WMC1118: TwoWay binding target 'value_prop' must be a dependency property
Однако меня это очень смущает, потому что я сделал value_prop
свойство зависимости.Как я могу сделать эту работу?
// MainPage.xaml
<local:attribute_slider Label="Scale" value_prop="{x:Bind texture_showcase_vm.current_texture.scale, Mode=TwoWay}"/>
// attribute_slider.xaml
<UserControl
x:Class="wzrd_editor.attribute_slider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wzrd_editor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" >
<TextBlock x:Name="scale_label" Text="{x:Bind Label, Mode=OneWay}" HorizontalAlignment="Left" />
<TextBlock x:Name="scale_text_value" Text="{x:Bind value_prop, Mode=TwoWay}" HorizontalAlignment="Right"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.RightOf="scale_label" />
<Slider x:Name="Scale" Value="{x:Bind value_prop, Mode=TwoWay}" Width="200" Orientation="Horizontal" Minimum="0" Maximum="10" StepFrequency="0.01" TickFrequency="0.01" SnapsTo="StepValues" TickPlacement="None"
RelativePanel.Below="scale_label"
RelativePanel.AlignRightWith="scale_text_value"
RelativePanel.AlignLeftWith="scale_label"
RelativePanel.AlignRightWithPanel="True" />
</StackPanel>
</UserControl>
// attribute_slider.idl
namespace wzrd_editor
{
[bindable]
[default_interface]
runtimeclass attribute_slider : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
attribute_slider();
static Windows.UI.Xaml.DependencyProperty LabelProperty{ get; };
static Windows.UI.Xaml.DependencyProperty value_property{ get; set; };
String Label;
Single value_prop;
}
}
attribute_slider.h
namespace winrt::wzrd_editor::implementation
{
struct attribute_slider : attribute_sliderT<attribute_slider>
{
attribute_slider();
static Windows::UI::Xaml::DependencyProperty LabelProperty();
static Windows::UI::Xaml::DependencyProperty value_property();
static void value_property(Windows::UI::Xaml::DependencyProperty const& value);
hstring Label();
void Label(hstring const& value);
float value_prop();
void value_prop(float const& value);
winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
void PropertyChanged(winrt::event_token const& token) noexcept;
private:
static Windows::UI::Xaml::DependencyProperty m_labelProperty;
static Windows::UI::Xaml::DependencyProperty m_value_property;
hstring m_label = L"";
float m_value = 0.0f;
winrt::event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_property_changed;
void raise_property_changed(hstring const& property_name)
{
m_property_changed(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs(property_name));
}
template <class T>
void update_value(hstring const& property_name, T & var, T value)
{
if (var != value)
{
var = value;
raise_property_changed(property_name);
}
}
};
}
// attribute_slider.cpp
namespace winrt::wzrd_editor::implementation
{
Windows::UI::Xaml::DependencyProperty attribute_slider::m_labelProperty =
Windows::UI::Xaml::DependencyProperty::Register(
L"Label",
winrt::xaml_typename<winrt::hstring>(),
winrt::xaml_typename<wzrd_editor::attribute_slider>(),
Windows::UI::Xaml::PropertyMetadata{ nullptr }
);
Windows::UI::Xaml::DependencyProperty attribute_slider::m_value_property =
Windows::UI::Xaml::DependencyProperty::Register(
L"value_prop",
winrt::xaml_typename<winrt::hstring>(),
winrt::xaml_typename<wzrd_editor::attribute_slider>(),
Windows::UI::Xaml::PropertyMetadata{ nullptr }
);
attribute_slider::attribute_slider()
{
InitializeComponent();
}
hstring attribute_slider::Label()
{
return m_label;
}
void attribute_slider::Label(hstring const& value)
{
update_value(L"Label", m_label, value);
}
float attribute_slider::value_prop()
{
return m_value;
}
void attribute_slider::value_prop(float const& value)
{
update_value(L"value_prop", m_value, value);
}
Windows::UI::Xaml::DependencyProperty attribute_slider::LabelProperty()
{
return m_labelProperty;
}
Windows::UI::Xaml::DependencyProperty attribute_slider::value_property()
{
return m_value_property;
}
void attribute_slider::value_property(Windows::UI::Xaml::DependencyProperty const& value)
{
m_value_property = value;
}
winrt::event_token attribute_slider::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return m_property_changed.add(handler);
}
void attribute_slider::PropertyChanged(winrt::event_token const& token) noexcept
{
m_property_changed.remove(token);
}
}