/// <remarks>This overload allows to pass a string <paramref name="path"/> instead of a pathExpression. A pathExpression only uses the part after the last '.', while <paramref name="path"/> allows to specify paths that contain '.'</remarks>
 public static TDependencyObject BindWithString <TDependencyObject, TPropertyValue>(
     this DependencyProperty <TDependencyObject, TPropertyValue> property,
     string path               = bindingContextPath,
     BindingMode mode          = BindingMode.Default,
     IValueConverter converter = null,
     object converterParameter = null,
     string converterLanguage  = null,
     UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default,
     object source = null,
     TPropertyValue targetNullValue = default,
     TPropertyValue fallbackValue   = default
     ) where TDependencyObject : DependencyObject
 => property.SetBinding(new System.Windows.Data.Binding
 {
     Path               = new System.Windows.PropertyPath(path),
     Mode               = mode,
     Converter          = converter,
     ConverterParameter = converterParameter,
     //ConverterLanguage = converterLanguage, // TODO: figure out correct default; can't be null
     UpdateSourceTrigger = updateSourceTrigger,
     Source = source,
     // TODO: RelativeSource
     TargetNullValue = targetNullValue,
     FallbackValue   = fallbackValue,
 });
 /// <summary>Bind a <see cref="System.Windows.DependencyProperty"/> in a <see cref="CSharpMarkup.Wpf.Style"/>. Use to specify a parameter for e.g. <see cref="Style{T}((System.Windows.DependencyProperty property, UIObject value)[])"/></summary>
 /// <param name="pathExpression">viewModel.Property or viewModel.Property1.Property2 or (SomeExpression.viewModel).Property <br />?. can be used safely - viewmodel instance is not required</param>
 public static (System.Windows.DependencyProperty, System.Windows.Data.Binding) Bind(
     this System.Windows.DependencyProperty property,
     object pathExpression     = null,
     BindingMode mode          = BindingMode.Default,
     IValueConverter converter = null,
     object converterParameter = null,
     string converterLanguage  = null,
     UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default,
     object source          = null,
     object targetNullValue = default,
     object fallbackValue   = default,
     [CallerArgumentExpression("pathExpression")] string pathExpressionString = default
     ) => (property, new System.Windows.Data.Binding
 {
        /// <remarks>This overload allows to pass a string <paramref name="path"/> instead of a pathExpression. A pathExpression only uses the part after the last '.', while <paramref name="path"/> allows to specify paths that contain '.'</remarks>
        public static TDependencyObject BindWithString <TDependencyObject>(
            this TDependencyObject target,
            string path               = bindingContextPath,
            BindingMode mode          = BindingMode.Default,
            IValueConverter converter = null,
            object converterParameter = null,
            string converterLanguage  = null,
            UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default,
            object source          = null,
            object targetNullValue = default,
            object fallbackValue   = default
            ) where TDependencyObject : DependencyObject, IDefaultBindProperty
        {
            var binding = new System.Windows.Data.Binding(path)
            {
                Mode               = mode,
                Converter          = converter,
                ConverterParameter = converterParameter,
                //ConverterLanguage = converterLanguage, // TODO: figure out correct default; can't be null
                UpdateSourceTrigger = updateSourceTrigger,
                // TODO: RelativeSource
                TargetNullValue = targetNullValue,
                FallbackValue   = fallbackValue,
            };

            if (source != null)
            {
                binding.Source = source;                 // In WPF, setting the binding Source to null prevents the binding from working, even though the value of Source in the created binding is null
            }
            System.Windows.Data.BindingOperations.SetBinding(
                target.UI,
                target.DefaultBindProperty,
                binding
                );
            return(target);
        }
 /// <summary>Bind to <typeparamref name="TDependencyObject"/>.DefaultBindProperty</summary>
 /// <param name="pathExpression">viewModel.Property or viewModel.Property1.Property2 or (SomeExpression.viewModel).Property <br />?. can be used safely - viewmodel instance is not required</param>
 public static TDependencyObject Bind <TDependencyObject>(
     this TDependencyObject target,
     object pathExpression     = null,
     BindingMode mode          = BindingMode.Default,
     IValueConverter converter = null,
     object converterParameter = null,
     string converterLanguage  = null,
     UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default,
     object source          = null,
     object targetNullValue = default,
     object fallbackValue   = default,
     [CallerArgumentExpression("pathExpression")] string pathExpressionString = default
     ) where TDependencyObject : DependencyObject, IDefaultBindProperty
 => target.BindWithString(
     Helpers.BindingExpressionToPath(pathExpressionString),
     mode,
     converter,
     converterParameter,
     converterLanguage,
     updateSourceTrigger,
     source,
     targetNullValue,
     fallbackValue
     );