【问题标题】:WPF "Cannot find source for binding" with ContentPresenters, and UserControlWPF“找不到绑定源”与 ContentPresenters 和 UserControl
【发布时间】:2012-12-31 10:51:01
【问题描述】:

我有一个:

System.Windows.Data 错误:4:找不到绑定源 参考“元素名称=测试”。绑定表达式:路径=值; 数据项=空;目标元素是 'Slider' (Name='');目标属性 是“值”(类型“双”)

在非常特殊的情况下出错。 我虽然是关于名称范围的问题,但我不知道如何解决它。

考虑以下 WPF 应用程序:

MyUserControl.xaml:

<UserControl x:Class="WpfApplication1.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Label Grid.Row="0" Content="Move me !"/>
        <Slider x:Name="Test" Grid.Row="0" Grid.Column="1" />
        <Label Grid.Row="1" Content="Binded slider"/>
        <ContentPresenter Grid.Row="1" Grid.Column="1">
            <ContentPresenter.Content>
                <Slider Value="{Binding Value, ElementName=Test}"/>
            </ContentPresenter.Content>
        </ContentPresenter>
    </Grid>
</UserControl>

MyUserControl.xaml.cs:

using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
        }
    }
}

MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="300" Height="120">

    <StackPanel>
        <Button Click="Button_Click" Content="Click me to show Sliders !" Height="25"/>
        <ContentPresenter x:Name="contentPresenter"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        private MyUserControl myUserControl;

        public MainWindow()
        {
            InitializeComponent();

            myUserControl = new MyUserControl();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            contentPresenter.Content = myUserControl;
        }
    }
}

鉴于 MyUserControl.xaml 的代码,我希望绑定的滑块与第一个滑块具有相同的值。

但是什么也没发生。

现在,棘手的部分:启动应用程序,单击按钮,移动第一个滑块,打开“WPF Inspector”并将其附加到应用程序。结果:绑定已修复。

你如何解释这种现象?

【问题讨论】:

  • 我对此进行了测试,在内容中添加了代码中的 MyUserControl 后,绑定出现了问题。如果您从工具箱将其添加到网格中,则绑定有效。

标签: c# .net wpf data-binding binding


【解决方案1】:

这样就可以了

    <!--<ContentPresenter Grid.Row="1" Grid.Column="1">
        <ContentPresenter.Content>-->
            <Slider Value="{Binding Value, ElementName=Test}" Grid.Column="1" Grid.Row="1"/>
        <!--</ContentPresenter.Content>
    </ContentPresenter>-->

因为 Slider 位于内容演示者内部,所以您无法访问它的值。您需要绑定到相同的 viewmodel 属性来实现这一点,同时将它放在内容呈现器中。

编辑

Get Prism 和用户一个 ViewModel...我不会详细说明...但是您需要做的是这个...

下载完所有内容后,将Microsoft.Practices.Prism dll 添加到您的项目中

创建一个新类 (ViewModel)。随意命名。我打电话给我的MyUserControlViewModel,让它看起来像这样

using Microsoft.Practices.Prism.ViewModel;

namespace YourNamespace
{
    public class MyUserControlViewModel : NotificationObject
    {
        private double _sliderValue;

        public double SliderValue
        {
            get { return _sliderValue; }
            set
            {
                _sliderValue = value;
                RaisePropertyChanged(() => SliderValue);
            }
        }

    }
}

像这样更改用户控件中的 XAML

<Slider x:Name="Test" Grid.Row="0" Grid.Column="1" Value="{Binding SliderValue, Mode=TwoWay}"/>        
<ContentPresenter Grid.Row="1" Grid.Column="1">
    <ContentPresenter.Content>
        <Slider Value="{Binding SliderValue}"/>
    </ContentPresenter.Content>
</ContentPresenter>

并将这行代码添加到您的 MyUserControl.cs 文件中

DataContext = new MyUserControlViewModel();

现在 ViewModel 接管了繁重的工作...您将第一个滑块的值绑定到属性 SliderValue(Mode=TwoWay 表示此控件可以设置和获取属性的状态)并且您已将另一个滑块绑定到相同的SliderValue,使其与第一个滑块同步移动

希望对你有帮助

【讨论】:

  • 我必须将 ContentPresenter 和 Slider 保留在其中。所以,当你说:“你需要绑定到相同的视图模型属性来实现这一点,同时将它放在内容呈现器中。” ?
  • 感谢您提供此详细信息。有用。但我仍然想知道为什么当我把 myUserControl = new MyUserControl();在 Button_Click 方法中,它可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
相关资源
最近更新 更多