Create a menu setting popup with a slider inside ContentControl
I'm creating a slider that modifies a variable inside unreal engine by using onewaytosource binding mode (changing volume setting for example). Now I need to create an event that triggered when the value changed but I'm having a hard time doing.
I have a Popup element with a ContentControl child that has the property Style asign to a Style that has the Slider. Something like this
The popup is enabled when a button is pressed. When changing the slider will change the "VolumeMaster" in unreal. I'm having trouble binding the ValueChanged property of Slider to an event so I'd like to ask how to correctly bind this property when I'm at the UserControl root element (in blueprint and c++ if possible). The intention was to create a function (blueprint) with the name "OnMasterVolumeChanged" to print the current value of Slider. Tried using FindName to search for the slider but failed. I would like to be able to bind the function without changing the above structure if possible.
Can anyone guide me to the right direction. I'm only a beginner in xaml/wpf so any pointer would be appreciated.
I have a Popup element with a ContentControl child that has the property Style asign to a Style that has the Slider. Something like this
Code: Select all
<UserControl x:Class="MyNameSpace.Home" ...>
<UserControl.Resources>
<ControlTemplate x:Key="Template.ItemToolTip" TargetType="{x:Type ContentControl}">
<Grid>
<StackPanel Orientation="Horizontal" Margin="0,10,0,10" HorizontalAlignment="Stretch">
<TextBlock Text="Volume: "/>
<Slider x:Name="MasterVolume" Margin="0,10,0,10" Width="270" Value="{Binding MasterVolume, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" ValueChanged="{Binding OnMasterVolumeChanged}">
</Slider>
</StackPanel>
</Grid>
</ControlTemplate>
<Style x:Key="Style.ItemToolTip" TargetType="{x:Type ContentControl}">
<Setter Property="Template" Value="{StaticResource Template.ItemToolTip}"/>
</Style>
</UserControl.Resources>
<Grid>
<Popup IsOpen="{Binding IsChecked, ElementName=MenuButton}" x:Name="Popup" StaysOpen="False" AllowsTransparency="True" Placement="RelativePoint" PlacementTarget="{Binding ElementName=PopupPosition}">
<ContentControl x:Name="MenuPopup" Style="{StaticResource Style.ItemToolTip}"/>
</Popup>
</Grid>
</UserControl>
Can anyone guide me to the right direction. I'm only a beginner in xaml/wpf so any pointer would be appreciated.
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: Create a menu setting popup with a slider inside ContentControl
Hi,
I think you don't need to create a ControlTemplate+Style in order to show it in the popup (unless you are reusing that style in more places), you can just have the elements directly inside the popup. This will allow you to search for any element inside the popup by calling FindName from the UserControl code-behind. If you still want to use a template, you then need to first call FindName to find the "MenuPopup" element, and then call on that element GetTemplateChild to search for elements inside the template.
Regarding ValueChanged, you should follow the documentation about events. Just set the name of the method you want to call when the event is raised and override ConnectEvent in the usercontrol code-behind to hook that method with the event.
Hope this helps.
I think you don't need to create a ControlTemplate+Style in order to show it in the popup (unless you are reusing that style in more places), you can just have the elements directly inside the popup. This will allow you to search for any element inside the popup by calling FindName from the UserControl code-behind. If you still want to use a template, you then need to first call FindName to find the "MenuPopup" element, and then call on that element GetTemplateChild to search for elements inside the template.
Regarding ValueChanged, you should follow the documentation about events. Just set the name of the method you want to call when the event is raised and override ConnectEvent in the usercontrol code-behind to hook that method with the event.
Code: Select all
<UserControl x:Class="MyNameSpace.Home" ...>
<Grid>
<Popup IsOpen="{Binding IsChecked, ElementName=MenuButton}" x:Name="Popup" StaysOpen="False" AllowsTransparency="True"
Placement="RelativePoint" PlacementTarget="{Binding ElementName=PopupPosition}">
<Grid>
<StackPanel Orientation="Horizontal" Margin="0,10,0,10" HorizontalAlignment="Stretch">
<TextBlock Text="Volume: "/>
<Slider x:Name="MasterVolume" Margin="0,10,0,10" Width="270"
Value="{Binding MasterVolume, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" ValueChanged="OnMasterVolumeChanged">
</Slider>
</StackPanel>
</Grid>
</Popup>
</Grid>
</UserControl>
Code: Select all
class Home...
{
bool ConnectEvent(BaseComponent* source, const char* event, const char* handler) override
{
NS_CONNECT_EVENT(Slider, ValueChanged, OnMasterVolumeChanged);
return false;
}
void OnMasterVolumeChanged(BaseComponent* sender, const RoutedPropertyChangedEventArgs<float>& args)
{
...
}
};
Re: Create a menu setting popup with a slider inside ContentControl
Thanks it worked! I also learned that GetTemplateChild doesn't return anything if the popup is not enabled.
But there's a problem. After I implemented the ConnectEvent method for the Home class exactly like above and assign the OnMasterVolumeChanged to ValueChanged in xaml, it worked but crashed when I stop the game in ue editor when the slider's thumb wasn't left at the original position/value (i.e. 0.0). When I start the game and move the slider's thumb back and forth then leave it at the original position, nothing crashes when I exit the game.
The exception throws me to the mPtr->Release() in Reset method of Ptr class of Noesis.
I didn't save any reference to any object. Tried to comment out the ConnectEvent method then rebuild, it didn't crash so the problem is the ConnectEvent I think.
But there's a problem. After I implemented the ConnectEvent method for the Home class exactly like above and assign the OnMasterVolumeChanged to ValueChanged in xaml, it worked but crashed when I stop the game in ue editor when the slider's thumb wasn't left at the original position/value (i.e. 0.0). When I start the game and move the slider's thumb back and forth then leave it at the original position, nothing crashes when I exit the game.
The exception throws me to the mPtr->Release() in Reset method of Ptr class of Noesis.
I didn't save any reference to any object. Tried to comment out the ConnectEvent method then rebuild, it didn't crash so the problem is the ConnectEvent I think.
Re: Create a menu setting popup with a slider inside ContentControl
Does it crash if you leave OnMasterVolumeChanged empty?
Could you paste here the code for OnMasterVolumeChanged?
Could you paste here the code for OnMasterVolumeChanged?
Re: Create a menu setting popup with a slider inside ContentControl
I just checked, it still crashes when OnMasterVolumeChanged is left empty. Here's the definition:
Code: Select all
void Home::OnMasterVolumeChanged(Noesis::BaseComponent* sender, const Noesis::RoutedPropertyChangedEventArgs<float>& args)
{
if (auto slider = Noesis::DynamicCast<Noesis::Slider*>(sender))
{
UE_LOG(LogTemp, Warning, TEXT("c++ Master: %f"), slider->GetValue());
}
else
{
UE_LOG(LogTemp, Warning, TEXT("sender is not slider!!!"));
}
}
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: Create a menu setting popup with a slider inside ContentControl
Could you try removing the binding from the Slider's Value property while still keeping the ConnectEvent implementation?
Let me know if you get a crash when stopping.
Let me know if you get a crash when stopping.
Re: Create a menu setting popup with a slider inside ContentControl
- Not assigning any value to the Value property (effectively not binding) while still keeping the ConnectEvent implementation doesn't trigger any crash
- Tried to binding to a variable that doesn't exist (say changing the name from VolumeMaster to VolumeMaster123) while still keeping the ConnectEvent implementation, it crashed
- Kept the binding attempt and the ConnectEvent impl but assinging ValueChanged property to an invalid value also doesn't trigger any crash
- Tried to binding to a variable that doesn't exist (say changing the name from VolumeMaster to VolumeMaster123) while still keeping the ConnectEvent implementation, it crashed
- Kept the binding attempt and the ConnectEvent impl but assinging ValueChanged property to an invalid value also doesn't trigger any crash
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: Create a menu setting popup with a slider inside ContentControl
We found and fixed the issue you described, it was trying to call the event handler during the control destruction.
The fix will be available in the next version release (3.1.6).
Thanks a lot for your feedback and help.
The fix will be available in the next version release (3.1.6).
Thanks a lot for your feedback and help.
Who is online
Users browsing this forum: Google [Bot] and 17 guests