无法将XAML按钮可见性与C#视图模型专用可见性变量绑定

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法将XAML按钮可见性与C#视图模型专用可见性变量绑定相关的知识,希望对你有一定的参考价值。

我想将XAML文件中的按钮可见性绑定到关联的C#视图模型代码中的私有Visibility变量。运行代码后,该按钮将继续显示而不是隐藏在私有可见性变量中定义的按钮。在阅读互联网上对类似问题的许多回复之后,我尝试了很多事情。

在输出窗口中看到的以下运行时错误已停止产品开发:

System.Windows.Data错误:40:BindingExpression路径错误:在'object''CalibrationSet'(HashCode = 40040273)'上找不到'SaveCalButtonVisibility'属性。 BindingExpression:Path = SaveCalButtonVisibility; DataItem ='CalibrationSet'(HashCode = 40040273);目标元素是'Button'(Name ='');目标属性为“可见性”(类型为“可见性”)

当前对象是CalibrationSetList,由于某种原因,它似乎试图将XAML保存校准按钮可见性属性绑定到DataItem=CalibrationSet Path=SaveCalButtonVisibility路径。我认为这应该绑定到DataItem=CalibrationSetList Path=SaveCalButtonVisibility路径才能正常工作。我不知所措,无法完成此绑定。

开发环境是带有Infragistics 2013.2。的Microsoft Visual Studio 2010。 XAML和C#代码如下所示,其中不包含无关的代码。该代码是按照MVVM模式,WPF和PRISM 4.0编写的]

非常感谢任何帮助,建议或继续进行的对话。

XAML代码:

<!-- CalibrationSetList.xaml -->

<UserControl 
    x:Class="Method.Control.CalibrationSetList"
    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" 
    xmlns:I18N="clr-namespace:I18N;assembly=I18N" 
    xmlns:I18NStrings="clr-namespace:I18N.Strings;assembly=I18N.Strings"
    xmlns:Conv="clr-namespace:Converters;assembly=Converters"
    mc:Ignorable="d" 
    xmlns:Local="clr-namespace:Method.Control"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:AuthInfrastructure="clr-namespace:Authorization.Components;assembly=Authorization.Components"
    xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"    >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"  />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0" Visibility="{Binding Path=CalibrationSetListControl}">
            <Grid Visibility="{Binding Path=CalibrationSetListVisibility}"  >
                <Grid.Resources>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                </Grid.Resources>

                <DataGrid EnableRowVirtualization="False" 
                          EnableColumnVirtualization="False" 
                          IsReadOnly="True" 
                          ItemsSource="{Binding CalibrationCollection, Mode=TwoWay}" 
                          SelectedValue="{Binding Path=SelectedCalibrationSetValue}" 
                          HorizontalGridLinesBrush="Transparent" 
                          VerticalGridLinesBrush="Transparent" Margin="30">

                    <DataGrid.Columns>

<!--…………………………………->

                        <!--Save Calibration button-->
                        <DataGridTemplateColumn Width="125">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>

                                    <Button  Style="{DynamicResource CustomButton}" 

                                         Visibility="{Binding Path=SaveCalButtonVisibility,Mode=TwoWay,
                                                             diag:PresentationTraceSources.TraceLevel=High}"

                                         HorizontalAlignment="Center" 
                                         VerticalAlignment="Center" 
                                         Command="{Binding Path=DataContext.SaveCalibrationClick,
                                                                RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}}}" 
                                         CommandParameter="{Binding}" >
                                        <Button.Content>
                                            <MultiBinding Converter="{Conv:StringToLocalizedString ResourceKey=SaveCalibration}">
                                                <Binding  RelativeSource="{RelativeSource AncestorType=UserControl}" 
                                                                 Path="DataContext.SelectedLanguage"></Binding>
                                            </MultiBinding>
                                        </Button.Content>
                                        <i:Interaction.Behaviors>
                                            <AuthInfrastructure:ControlBehavior x:Name="btnCalibrationSetSave" 
                                                          VMBounded="CalibrationSetSave" ModuleName="Calibration" />
                                        </i:Interaction.Behaviors>
                                    </Button>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>

                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
<!--…………………………………->
        <!--Calibration Set Control-->
        <Grid Visibility="{Binding Path=CalibrationSetControl}" HorizontalAlignment="Left" Width="762">
            <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Local:CalibrationSet 
                Grid.Row="0" 
                Grid.Column="0" 
                DataContext="{Binding CalibrationSetViewModelContext,Mode=TwoWay}" 
                ScrollViewer.HorizontalScrollBarVisibility="Auto" 
                ScrollViewer.VerticalScrollBarVisibility="Auto">
            </Local:CalibrationSet>
        </Grid>
        <!--End Calibration Set Control-->
    </Grid>
</UserControl>

匹配C#代码:

// CalibratonSetListViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using DataStructures;
using Framework;
using Method.Component;
using Method.Control.Calibration.Interface;
using Microsoft.Practices.Prism.Regions;
using EventAggregation;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.ServiceLocation;
using ViewModel.Base;
using Microsoft.Practices.Prism;
using CustomMessageBox;
using Chromatogram.DataDisplay.Control;

namespace Method.Control
{
    /// <summary>
    /// Set or Get CalibrationSetViewModelContext
    /// </summary>
    public class CalibrationSetListViewModel : ViewModelBase
    {
        #region Variables

//………………………………

        /// <summary>
        /// Save Cal Button Visibility
        /// </summary>
        private Visibility m_SaveCalButtonVisibility;

//………………………………

        #endregion

        #region Properties

//………………………………

        /// <summary>
        /// Set or Get Save Cal Button Visibility 
        /// </summary>
        public Visibility SaveCalButtonVisibility
        {
            get
            {
                return m_SaveCalButtonVisibility;
            }
            set
            {
                m_SaveCalButtonVisibility = value;
                OnPropertyChanged(() => SaveCalButtonVisibility);
            }
        }
//………………………………
       #endregion

        #region Constructor

        /// <summary>
        ///  Initializes new instance of MethodListViewModel
        /// </summary>
        /// <param name="methodId">MethodId</param>
        /// <param name="peakDataProvider">PeakDataProvider</param>
        public CalibrationSetListViewModel(int methodId, IPeakDataProvider peakDataProvider)
        {
            try
            {
                m_DataDisplayOfflineViewModel = new DataDisplayOfflineViewModel(true);  // gain access to member functions

                m_MethodId = methodId;
                m_PeakDataProvider = peakDataProvider;
                m_CalibrationSetListVisibility = Visibility.Visible;
                m_CreateButtonVisibility = Visibility.Collapsed;
                m_SaveCalButtonVisibility = Visibility.Collapsed;

                GetCalibrationsList();
                CreateCalibrationClick = new RelayCommand(parm => this.CreateCalibration());
                DeleteCalibrationClick = new RelayCommand(this.DeleteCalibration);
                SaveCalibrationClick = new RelayCommand(this.SaveCalibration);

                CalibrationDetailsClick = new RelayCommand(this.CalibrationDetails);
                CalibrationResultClick = new RelayCommand(this.CalibrationResult);

                //Publish menu clicked event
                m_EventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
                MenuHomePage menuHomePage = MenuHomePage.CalibrationSet;
                m_EventAggregator.GetEvent<ToolBarChange>().Publish(menuHomePage);

                SetCalibrationVisibility();

                //Subscribe CreateNewCalibration method
                m_CreateNewCalibration = m_EventAggregator.GetEvent<ToolBarCreateNewCalibrationEvent>();
                m_CreateNewCalibrationToken = m_CreateNewCalibration.Subscribe(createNewCalibration);

            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        #region Public Methods
//………………………………
      #endregion

      #region Public Methods
//………………………………
      #endregion

      #region Private Methods


      /// <summary>
      /// Create New CalibrationSet
      /// </summary>
      /// <returns></returns>
      private Entities.CalibrationSet CreateNewCalibrationSet()
      {
          Entities.CalibrationSet newCalibrationSet = new Entities.CalibrationSet();
          newCalibrationSet.CalibrationSetId = 0;
          newCalibrationSet.CalibrationSetNumber = 1;
          newCalibrationSet.AmountUnits = 2;
          return newCalibrationSet;
      }
//………………………………
        #endregion

    }
}
答案

假设您的CalibrationSetList绑定到CalibrationSetListViewModel(可能很难,很难说),问题是UserControl(可能是CalibationSetListViewModel)和网格中的一个单元格(它将是网格绑定到的集合中的单个项目)。

要将这些属性(默认情况下绑定到集合中各个项目的属性)绑定到顶级ViewModel,请使用:

{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, 
         Path=DataContext.SaveCalButtonVisibility }

希望有所帮助

以上是关于无法将XAML按钮可见性与C#视图模型专用可见性变量绑定的主要内容,如果未能解决你的问题,请参考以下文章

无法以编程方式设置列表视图中按钮的可见性

在活动中更改列表视图的按钮可见性

在按钮上单击列表视图中列的可见性应设置为 false

将 XAML 中的可见性绑定到可见性属性

使按钮在 DataGrid 中可见

XAML ContentControl 不改变可见性