【问题标题】:Binding properties to DataTemplate将属性绑定到 DataTemplate
【发布时间】:2018-09-30 23:49:55
【问题描述】:

我正在使用DataTemplate,它位于ResourceDictionary 文件中。

<DataTemplate x:Key="AlertWarningMessage">
    <Grid>
        <Border Visibility="{Binding DataContext.Visibility}" Background="{StaticResource ResourceKey=AlertWarningMessageBackground}" HorizontalAlignment="Stretch" Height="30">
            <WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock Text="WARNING !" FontWeight="Bold" Foreground="{StaticResource ResourceKey=AlertWarningMessageForeground}" FontSize="13"/>
                <TextBlock Text="{Binding DataContext.Message}" Foreground="{StaticResource ResourceKey=AlertWarningMessageForeground}" Margin="5,0,0,0"/>
            </WrapPanel>
        </Border>
    </Grid>
</DataTemplate>

我将这个字典合并到我的UserControl 中,我正在使用这个模板:

<ContentControl ContentTemplate="{StaticResource AlertWarningMessage}" Grid.Row="2" Margin="0,2,0,0" DataContext="{Binding AlertSummary, UpdateSourceTrigger=PropertyChanged}" />

在我的虚拟机中,我正在使用一个具有 2 个属性的类:

    Public Class AlertInfos
        Public Property Visibility As Visibility
        Public Property Message As String

        Public Sub New(p_visibility As Visibility, p_msg As String)
            Me.Visibility = p_visibility
            Me.Message = p_msg
        End Sub
    End Class

Property VM 作为我的类:

    Private _alertSummary As AlertInfos
    Public Property AlertSummary() As AlertInfos
        Get
            Return _alertSummary
        End Get
        Set(ByVal value As AlertInfos)
            _alertSummary = value
            RaisePropertyChanged("AlertSummary")
        End Set
    End Property

此对象的属性设置为CollapsedString.Empty

接下来,我改变这个对象的值,像这样:

    Public Sub ShowAlert()
        Me.AlertSummary.Message = "Test"
        Me.AlertSummary.Visibility = Visibility.Visible
        'Me.StartTimerAlert()
        RaisePropertyChanged("AlertSummary")
    End Sub

但它不起作用。有2个问题:

  • 一开始,当Visibility 设置为Collapsed 时,Border 是可见的。
  • 当我更改 Message 属性时,它没有视觉更新。

我认为我的Binding 有问题,但我不知道在哪里。我尝试了不同的东西,但总是有这些问题。 此外,我已经将属性直接绑定在ContentControl 下方的TextBlockBinding 工作查找中。

你有什么想法吗?

【问题讨论】:

    标签: wpf xaml binding datatemplate


    【解决方案1】:

    您应该将数据模板更改为:

     <DataTemplate x:Key="AlertWarningMessage">
            <Grid>
                <Border Visibility="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext.Visibility}" Background="AliceBlue" HorizontalAlignment="Stretch" Height="30">
                    <WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <TextBlock Text="WARNING !" FontWeight="Bold" Foreground="Red" FontSize="13"/>
                        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext.Message}" Foreground="Red" Margin="5,0,0,0"/>
                    </WrapPanel>
                </Border>
            </Grid>
        </DataTemplate>
    

    还有你的 AlertInfos (它在 C# 上,所以试着把它翻译成 VB)

    public class AlertInfos
    {
        private string message;
    
        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                if (this.message != value)
                {
                    this.message = value;
                }
            }
        }
        private Visibility visibility;
    
        public Visibility Visibility
        {
            get
            {
                return this.visibility;
            }
            set
            {
                if (this.visibility != value)
                {
                    this.visibility = value;
                }
            }
        }
    }
    

    它应该可以工作,至少它可以在我的电脑上工作

    【讨论】:

    • 所以...我添加了 RelativeSourcePath => 效果更好,但不能 100% 工作(Get 只达到了一次(一开始),但是不是在更新之后)。现在,我将Inherits GalaSoft.MvvmLight.ViewModelBase 添加到我的班级(以及RaisePropertyChanged 按属性),并且我的DataTemplate 中的Grid 具有DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentControl}}",并且绑定仅针对属性名称(Visibility消息)。非常感谢!
    • 这就是为什么我问你在我的另一个答案中是否有 INotifyPropertyChanged。每次更改时都应该提高它。 Galas 我帮助了你:) 请支持我的答案,这样你也可以帮助我:)
    • 在您提出第一个问题后,我尝试 Implements INotifyPropertyChanged 上课,但没有成功。我认为这是因为 RelativeSource 丢失了。我已经赞成你的回答,但是因为我只有 3 个 Reputation,它还不是会计(需要 15 个):/
    【解决方案2】:

    我不熟悉 VB 但 Message 需要 RaisePropertyChanged

    可见性通常也被绑定了 bools,它们也 RaisePropertyChanged - 然后使用 BooleanToVisibilityConverter

    确保您的属性是公开的 - 具有私有的支持变量和 RaisePropertyChanged。

        private bool _isSomethingVisibile;
        public bool IsSomethingVisibile
        {
            get { return _isSomethingVisibile; }
            set
            {
                _isSomethingVisibile = value;
                RaisePropertyChanged();
            }
        }
    

    您无需在绑定前加上隐含的“DataContext”。

    【讨论】:

    • 您是说我应该使用 2 个属性而不是我的对象?所以使用RaisePropertyChanged,绑定会起作用吗?
    • 您的数据上下文应该是保存数据的对象。您要在该对象上显示的数据需要是一个公共属性,并带有获取集通知。
    • 我试图对我的类进行继承,但绑定不再起作用。 我尝试了另一种方法:我的 VM 中的 2 个属性(VisibilityMessage),并将 DataTemplate 组件绑定到这 2 个属性。它不工作。但如果我直接在我的 UserControl 中执行此操作,就可以了。所以问题是当我使用模板时,但我不知道为什么。
    • 检查您的输出窗口以确保您没有任何绑定错误。发布您如何将 UI 绑定到您的对象。
    猜你喜欢
    • 2013-03-23
    • 2012-04-11
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2013-01-01
    • 2011-10-15
    相关资源
    最近更新 更多