【问题标题】:Binding with a Custom Control and DataTemplate与自定义控件和 DataTemplate 绑定
【发布时间】:2016-03-11 23:36:07
【问题描述】:

我知道这个问题已经被问了一遍又一遍,我已经在我的代码中加入了很多建议的更改,但直到现在似乎没有任何效果。基本上我想扩展一些具有某些属性的控件。最简单的示例是具有新属性 IsInEditModeTextBox

public class EditableTextBox : TextBox
{
    public static readonly DependencyProperty IsInEditModeProperty =
     DependencyProperty.Register("IsInEditMode", typeof(bool), typeof(EditableTextBox),
          new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((EditableTextBox)o).IsInEditModeChanged(e)));

    private void IsInEditModeChanged(DependencyPropertyChangedEventArgs e)
    {
        IsInEditMode = (bool)e.NewValue;
    }

    [Bindable(true)]
    public bool IsInEditMode
    {
        get { return (bool)GetValue(IsInEditModeProperty); }
        set { SetValue(IsInEditModeProperty, value); }
    }
}

对应的DataTemplate

<Style TargetType="controls:EditableTextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Background" Value="{x:Null}"/>
    <Setter Property="BorderBrush" Value="{StaticResource LuculusDarkGrayBrush}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Foreground" Value="{StaticResource LuculusBlueBrush}"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:EditableTextBox">
                <TextBox x:Name="edTextBox" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" FontWeight="{TemplateBinding FontWeight}"
                        Background="{TemplateBinding Background}" SnapsToDevicePixels="True" Foreground="{TemplateBinding Foreground}" Text="{TemplateBinding Text}"/>

                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsInEditMode" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderThickness" Value="0" TargetName="edTextBox" />
                        <Setter Property="Cursor" Value="Arrow" TargetName="edTextBox"/>
                        <Setter Property="IsReadOnly" Value="True" TargetName="edTextBox"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsInEditMode" Value="True"/>
                            <Condition Property="IsKeyboardFocusWithin" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="FontWeight" Value="Bold" TargetName="edTextBox"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsInEditMode" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="IsReadOnly" Value="False" TargetName="edTextBox"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

控件绑定到 viewmodel 属性,像这样

<controls:EditableTextBox IsInEditMode="{Binding IsInEditMode}"/>

绑定不起作用。如果我直接输入布尔值,则行为符合预期。

提前致谢

乔恩

【问题讨论】:

  • 必须尝试“{Binding IsInEditMode,Mode=Twoway}”并实施 INPC,因为您说它是 VM 属性。
  • INotifyPropertyChanged 用于 ViewModel,Mode=TwoWay 不会改变行为

标签: c# wpf binding datatemplate


【解决方案1】:

您不必使用 IsInEditModeChanged,只需删除这部分即可。另外,删除 BindableAttribute。

不要忘记为您的模型实现 INotifyPropertyChanged。我测试了这个套件,它工作正常。控制:

public static readonly DependencyProperty IsInEditModeProperty =
 DependencyProperty.Register("IsInEditMode", typeof(bool), typeof(EditableTextBox),
 new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

public bool IsInEditMode
{
    get { return (bool)GetValue(IsInEditModeProperty); }
    set { SetValue(IsInEditModeProperty, value); }
}

测试绑定:

<wpfApplication4:EditableTextBox IsInEditMode="{Binding Path=EditMode, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">

视图模型:

private bool editMode;
public bool EditMode
{
    get { return editMode; }
    set
    {
        editMode = value;
        OnPropertyChanged();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    • 2012-12-12
    • 1970-01-01
    相关资源
    最近更新 更多