我正在使用scalar_slider
制作一个名为UserControl
的自定义滑块。我想用两种方式绑定其中一个DependencyProperty
。
问题在于,在scalar_slider
内部进行的值更改未更新回正确实现vm
的父级视图模型INotifyPropertyChanged
。我认为问题与我在MainPage.xaml
中设置绑定有关。
// MainPage.xaml
<local:scalar_slider scalar_value="{x:Bind vm.my_scalar_value Mode=TwoWay}" />
// scalar_slider.xaml
<UserControl
x:Class="transformations.scalar_slider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:transformations"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel>
<TextBox Text="{x:Bind scalar_value, Mode=TwoWay}"/>
<Slider Value="{x:Bind scalar_value, Mode=TwoWay}"/>
</StackPanel>
</UserControl>
// scalar_slider.idl
namespace transformations
{
[default_interface]
runtimeclass scalar_slider : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
scalar_slider();
static Windows.UI.Xaml.DependencyProperty scalar_valueProperty;
Single scalar_value;
}
}
// scalar_slider.h
namespace winrt::transformations::implementation
{
struct scalar_slider : scalar_sliderT<scalar_slider>
{
scalar_slider();
static Windows::UI::Xaml::DependencyProperty scalar_valueProperty();
static void scalar_valueProperty(Windows::UI::Xaml::DependencyProperty value);
float scalar_value();
void scalar_value(float value);
winrt::event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler);
void PropertyChanged(winrt::event_token const& token) noexcept;
template <class T>
void update_value(hstring const& property_name, T & var, T value)
{
if (var != value)
{
var = value;
raise_property_changed(property_name);
}
}
private:
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));
}
static Windows::UI::Xaml::DependencyProperty m_scalar_value_property;
float m_scalar_value = 0.0f;
};
}
// scalar_slider.cpp
namespace winrt::transformations::implementation
{
scalar_slider::scalar_slider()
{
InitializeComponent();
}
winrt::event_token scalar_slider::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return m_property_changed.add(handler);
}
void scalar_slider::PropertyChanged(winrt::event_token const& token) noexcept
{
m_property_changed.remove(token);
}
Windows::UI::Xaml::DependencyProperty scalar_slider::m_scalar_value_property = Windows::UI::Xaml::DependencyProperty::Register(
L"scalar_value",
winrt::xaml_typename<float>(),
winrt::xaml_typename<winrt::transformations::scalar_slider>(),
Windows::UI::Xaml::PropertyMetadata{ nullptr }
);
Windows::UI::Xaml::DependencyProperty scalar_slider::scalar_valueProperty()
{
return m_scalar_value_property;
}
void scalar_slider::scalar_valueProperty(Windows::UI::Xaml::DependencyProperty value)
{
m_scalar_value_property = value;
}
float scalar_slider::scalar_value()
{
return m_scalar_value;
}
void scalar_slider::scalar_value(float value)
{
update_value(L"scalar_value", m_scalar_value, value);
}
}
答案 0 :(得分:3)
关于您的代码,我发现您编写的scalar_slider
属性的get和set函数在scalar_slider.cpp中不正确,您可以像下面的代码一样更改它们。
您也可以阅读XAML custom (templated) controls with C++/WinRT以便更好地理解。
float scalar_slider::scalar_value()
{
return winrt::unbox_value<float>(GetValue(m_scalar_value_property));
}
void scalar_slider::scalar_value(float value)
{
SetValue(m_scalar_value_property, winrt::box_value(value));
m_property_changed(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs(L"scalar_value"));
}