How to create binding inside custom control automatically?

时光毁灭记忆、已成空白 提交于 2019-12-22 11:27:30

问题


I have my custom toolbar control with DependencyProperty IsBusy

Here is how I use it:

<Controls:myToolbar 
                Grid.ColumnSpan="5" Mode="DataEntry" 
                Status="{Binding State, Converter={StaticResource ViewEditingStateToToolbarStateConverter}}"
                IsBusy="{Binding IsBusy}"/>

By convention all my VM's inherit from base VM and have IsBusy property. So, I KNOW that this property will always be available on VM.

Now I have another 4 properties like this. Instead of adding them to XAML on all my views I want to know how to bind to this IsBusy automatically inside control's code so I don't have to bind in XAML?

EDIT

Actually, I found answer to my question: Silverlight: Programmatically binding control properties

Now, my question is:

Is it correct to apply this binding in constructor like this?

public myToolbar()
        {
            this.DefaultStyleKey = typeof(myToolbar);

            var binding = new Binding("IsBusy") { Mode = BindingMode.TwoWay };
            this.SetBinding(IsBusyProperty, binding); 
        }

Should I check if XAML binding (another binding) exist to this property and not bind? It works either way but I wonder if it's bad for performance, smells, etc?

What about doing this in onApplyTemplate. Is that better way?

if (GetBindingExpression(IsBusyProperty) == null)
            {
                var binding = new Binding("IsBusy") { Mode = BindingMode.TwoWay };
                this.SetBinding(IsBusyProperty, binding);
            }

回答1:


It would be bad if you tried to use this control with a view model which doesn't have the IsBusy property, but even then you'll receive just a debug warning in the output window, nothing to worry about.

As to the place of the binding, the constructor is appropriate if the dependency property which you are binding to doesn't perform any actions inside its callback. But if the property changed callback tries to call such functions as GetTemplateChild and retrieve inner controls - then you should move the binding to the OnApplyTemplate functions, because only there you can be assured that inner controls exist.

By the way, if your dependency proeprty doesn't have a property changed callback and is used only in the control template like {TemplateBinding IsBusy}, you can replace this line by {Binding IsBusy}. Something like this, either by using binding or data triggers:

<ControlTemplate TargetType="{x:Type Controls:myToolbar}">
    <Grid>
        <ContentControl x:Name="content" ... />
        <ProgressBar x:name="progress" ... />
    </Grid>
    <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding IsBusy}" Value="True">
            <Setter TargetName="progress" Property="Visibility" Value="Visible" />
        </DataTrigger>

The idea is simple: TemplateBinding is applied to dependency properties of the control, whereas Binding is applied to properties of the DataContext object or the view model and they can coexist without problems.



来源:https://stackoverflow.com/questions/8854034/how-to-create-binding-inside-custom-control-automatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!