0

我有一个自定义用户控件,它具有字符串类型的自定义依赖属性。它应该双向绑定到文本框,该文本框位于周围的应用程序中,如下所示:

<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl 
     ....
         MyString = "{Binding ElementName=TextBoxInHostApp, Path=Text, Mode=TwoWay}"
</ctrl:MyControl>

问题:

控件还应该具有显示依赖属性值的功能!

在 MyControl 中,我有一个简单的字符串属性“名称”,它应该更新 MyString 依赖属性值。

因此,通常,如果 MyString 未绑定到外部世界,您将在使用控件的 xaml 中进行编码:

<Textbox Name="TextBoxInHostApp"/>
<ctrl:MyControl 
     ....
         MyString = "{Binding Name}"
</ctrl:MyControl>

但这在我的情况下不可用。

尝试 1:我在用户控件 xaml 中使用了触发器:

<UserControl.Style>
    <Style>
        <Style.Setters>
            <Setter Property="local:MyControl.MyString" Value="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
        </Style.Setters>
    </Style>

现在这个触发器不起作用,因为这里已经设置了 dp 的“本地值”:

MyString = "{Binding ...

如果我注释掉:

<!--<MyString = "{Binding ...

...触发器工作正常,因为未设置“本地值”。

下一次尝试:我在 MyControls 视图模型中尝试了艰难的方法和代码:

public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
         RaisePropertyChanged("Name");

         MyOwningUICtrl.SetValue(MyControl.MyStringProperty, value); // ??
    }
}

我必须通过一个 DependencyObject 来调用一个 SetValue,这对 MVVM 来说是不愉快的。这种情况必须有更好的解决方案吗?

4

2 回答 2

3

这是设计使然

根据 WPF 的Dependency Property Precedence List,在 a 中本地指定的值<Tag>将始终优先于在 aStyle或 a中指定的值Trigger

一个常见的问题是在 a 中设置一个值<Tag>,然后尝试在 a 中更改它Style.Trigger。解决方案是将默认值设置为 a <Setter>in<Style>而不是 in <Tag>,这将允许触发值优先于样式值

<Style>
    <!-- Default Value
    <Setter Property="local:MyControl.MyString" 
            Value="{Binding ElementName=TextBoxInHostApp, Path=Text, Mode=TwoWay}"/>

    <Style.Triggers>
        <Trigger ...>
            <!-- Triggered Value -->
            <Setter Property="local:MyControl.MyString" 
                    Value="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
        </Trigger>
    </Style.Setters>
</Style>

但我实际上并没有在任何地方看到您的帖子中定义的触发器,所以我不确定这是否是您的问题。

我对代码的确切结构有点不清楚,但请记住,依赖属性有点像指向另一个值的指针。您可以将其设置为指向TextBox.Text或指向DataContext.Name,但不能同时设置两者。

如果你想同时设置TextBox.TextMyUserControl.MyString指向DataContext.Name,那么你应该"{Binding Name}"Natxo 建议的那样绑定这两个属性。

或者,如果您尝试绑定MyString到标签中未指定的情况,那么您可以尝试使用PriorityBinding此处为示例),或者只是将属性暴露给外界,让外部元素使用控件,如UserControl.NameMyString<ctrl:MyControl ...>Name<ctrl:MyControl Name="{Binding ...}" />

于 2013-03-25T14:40:42.643 回答
1

如果您在 Textbox 和 Mycontrol 中都显示相同的值...为什么不将它们绑定到该属性?:

<Textbox Name="TextBoxInHostApp" Text="{Binding Name}"/>
<ctrl:MyControl 
     ....
         MyString="{Binding Name}"
</ctrl:MyControl>
于 2013-03-25T14:21:54.210 回答