附加集合项丢失数据上下文

发布于 2024-07-18 01:13:57 字数 1301 浏览 13 评论 0原文

我创建了一个附加属性 AttachedBehaviorsManager.Behaviors,它将用作将事件与命令联系起来的 MVVM 帮助程序类。 该属性的类型为BehaviorCollection(ObservableCollection 的包装器)。 我的问题是行为命令的绑定最终总是为空。 当用在按钮上时,效果很好。

我的问题是为什么我会丢失集合内项目的 DataContext,以及如何修复它?

<UserControl x:Class="SimpleMVVM.View.MyControlWithButtons"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:behaviors="clr-namespace:SimpleMVVM.Behaviors"
             xmlns:con="clr-namespace:SimpleMVVM.Converters"
Height="300" Width="300">
<StackPanel>
        <Button Height="20" Command="{Binding Path=SetTextCommand}" CommandParameter="A" Content="Button A" />
     <Button Height="20" Command="{Binding Path=SetTextCommand}" CommandParameter="B" Content="Button B"/>
    <TextBox x:Name="tb" Text="{Binding Path=LabelText}">
        <behaviors:AttachedBehaviorsManager.Behaviors>
            <behaviors:BehaviorCollection>
                <behaviors:Behavior Command="{Binding Path=SetTextCommand}" CommandParameter="A" EventName="GotFocus"/>
            </behaviors:BehaviorCollection>
        </behaviors:AttachedBehaviorsManager.Behaviors>
    </TextBox>
</StackPanel>

I created an attached property, AttachedBehaviorsManager.Behaviors that is to be used as an MVVM helper class that ties events to commands. The property is of type BehaviorCollection (a wrapper for ObservableCollection). My issue is that the Binding for the Behavior's Command always winds up being null. When used on the buttons it works just fine though.

My question is why am I losing my DataContext on items inside of the collection, and how can I fix it?

<UserControl x:Class="SimpleMVVM.View.MyControlWithButtons"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:behaviors="clr-namespace:SimpleMVVM.Behaviors"
             xmlns:con="clr-namespace:SimpleMVVM.Converters"
Height="300" Width="300">
<StackPanel>
        <Button Height="20" Command="{Binding Path=SetTextCommand}" CommandParameter="A" Content="Button A" />
     <Button Height="20" Command="{Binding Path=SetTextCommand}" CommandParameter="B" Content="Button B"/>
    <TextBox x:Name="tb" Text="{Binding Path=LabelText}">
        <behaviors:AttachedBehaviorsManager.Behaviors>
            <behaviors:BehaviorCollection>
                <behaviors:Behavior Command="{Binding Path=SetTextCommand}" CommandParameter="A" EventName="GotFocus"/>
            </behaviors:BehaviorCollection>
        </behaviors:AttachedBehaviorsManager.Behaviors>
    </TextBox>
</StackPanel>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌 2024-07-25 01:13:57

您绑定到该命令是因为它使用 MVVM (Model-View-ViewModel< /a>) 模式。 此用户控件的数据上下文是一个 ViewModel 对象,其中包含公开命令的属性。 命令不需要是公共静态对象。

所示代码中的按钮执行没有问题。 它们绑定到视图模型中的 SetTextCommand:

class MyControlViewModel : ViewModelBase
{
    ICommand setTextCommand;
    string labelText;

    public ICommand SetTextCommand
    {
        get
        {
            if (setTextCommand == null)
                setTextCommand = new RelayCommand(x => setText((string)x));
            return setTextCommand;
        }
    }
    //LabelText Property Code...

    void setText(string text)
    {
        LabelText = "You clicked: " + text;
    }
}

问题是,行为中无法识别到在按钮中工作的相同 SetTextCommand 的绑定:Behavior。

You bind to the command because this is using the MVVM (Model-View-ViewModel) pattern. The datacontext of this user control is a ViewModel object containing a property that exposes the command. Commands do not need to be public static objects.

The buttons in the shown code have no problem executing. They are bound to to the SetTextCommand in the viewmodel:

class MyControlViewModel : ViewModelBase
{
    ICommand setTextCommand;
    string labelText;

    public ICommand SetTextCommand
    {
        get
        {
            if (setTextCommand == null)
                setTextCommand = new RelayCommand(x => setText((string)x));
            return setTextCommand;
        }
    }
    //LabelText Property Code...

    void setText(string text)
    {
        LabelText = "You clicked: " + text;
    }
}

The problem is that the binding to the same SetTextCommand that works in the buttons is not recognized in the behavior:Behavior.

度的依靠╰つ 2024-07-25 01:13:57

为什么要绑定命令? 命令应该这样设置:

<Button Command="ApplicationCommands.Open"/>

假设您像这样定义一个命令类:

namespace SimpleMVVM.Behaviors {
    public static class SimpleMvvmCommands {
        public static RoutedUICommand SetTextCommand { get; }
    }
}

您将像这样使用它:

<Button Command="behaviors:SimpleMvvmCommands.SetTextCommand"/>

MVVM 模式不适用于您使用它的方式。 您可以将命令处理程序放在虚拟机上,但命令本身应该位于静态上下文中。 有关详细信息,请参阅 MSDN 上的文档

Why are you binding to the command? Commands are meant to be setup this way:

<Button Command="ApplicationCommands.Open"/>

Suppose you define a command class like so:

namespace SimpleMVVM.Behaviors {
    public static class SimpleMvvmCommands {
        public static RoutedUICommand SetTextCommand { get; }
    }
}

You would use it like so:

<Button Command="behaviors:SimpleMvvmCommands.SetTextCommand"/>

The MVVM pattern isn't applicable the way you're using it. You'd put the command handler on the VM, but commands themselves are meant to be in the static context. Please refer to the documentation on MSDN for further information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文