简体   繁体   English

wpf主目录详细实现两路绑定需要PATH或XPATH

[英]wpf master detail implementation TWO WAY BINDING REQUIRES PATH OR XPATH

Allready have a two classes in master detail schema, 在主详细模式中已经有两个类,

the master class has a collection of detail master, and need (want) to perform all crude options inline. master类具有详细信息master的集合,并且需要(希望)内联执行所有原始选项。

Classes: 类:

public partial class Items
{
    public Items()
    {
        this.Detail = new HashSet<Detail>();
    }

    public decimal NumIdConcepto { get; set; }
    public string StrDescripcionConcepto { get; set; }

    public virtual ICollection<Detail> Detail { get; set; }
}

public partial class Detail
{
    public int IntTipoAsociado { get; set; }
    public decimal NumIdConcepto { get; set; }

    public virtual Items Items { get; set; }
    public virtual Master Master { get; set; }
}

public partial class Master
{
    public Master()
    {
        this.Detail = new HashSet<Detail>();
    }

    public int IntTipoAsociado { get; set; }
    public string StrDescripcionTipoAsociado { get; set; }

    public virtual ICollection<Detail> Detail { get; set; }
}

For editing purposes and limitations of EF generator must perform a conversion from HashSet to ObservableCollection for Detail collection of Master 出于编辑目的和EF生成器的限制,必须执行从HashSetObservableCollection的转换,以获取Master的Detail集合。

public class listToObservableCollection : BaseConverter, IValueConverter
{
    public HashSet<Detail> JustForPath { get; set; }
    public ObservableCollection<Detail> JustForPathObservable { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        HashSet<Detail> observableList = (HashSet<Detail>)value;
        JustForPathObservable = new ObservableCollection<Detail>(observableList);
        return JustForPathObservable;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        JustForPath = (HashSet<Detail>)value;
        return JustForPath;
    }
}

public abstract class BaseConverter : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}  

With this structure I want to generate a DataGrid wich allow me to add, delete, and edit Detail In line, Don't want to call another forms 通过这种结构,我想生成一个DataGrid,它允许我添加,删除和编辑明细行,不想调用其他表单

Like this: 像这样:

在此处输入图片说明

My XAML code look like this: 我的XAML代码如下所示:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModels="clr-namespace:Contratos.ViewModels" x:Class="Contratos.Views.TipoAsociado"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"
    xmlns:l="clr-namespace:Recursos;assembly=Recursos"
    Title="{Binding Title}" Height="Auto" Width="Auto">
<Window.DataContext>
    <ViewModels:TipoAsociadoVM/>
</Window.DataContext>
<Window.Resources>
    <l:listToObservableCollection x:Key="listoToObservable"/>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <DataGrid Grid.Row="1" 
              ItemsSource="{Binding Master}"  
              AutoGenerateColumns="False" 
              SelectionMode="Single"
              GridLinesVisibility="Vertical"
              CanUserAddRows="True"
              CanUserDeleteRows="True"
              x:Name="GridTipoAsociado"
              Margin="5" SelectionChanged="GridTipoAsociado_SelectionChanged">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <cmd:EventToCommand Command="{Binding _ICommandSelectionChange}"
                                    PassEventArgsToCommand="True"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Description" x:Name="Description">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding StrDescripcionTipoAsociado}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding StrDescripcionTipoAsociado }"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid Grid.Row="1" 
                        ItemsSource="{Binding Path=Detail,Converter={StaticResource listoToObservable},Mode=TwoWay}"
                        DisplayMemberPath="StrDescripcionConcepto"
                        AutoGenerateColumns="False" 
                        IsSynchronizedWithCurrentItem="True"
                        SelectionMode="Single"
                        SelectionUnit="Cell"
                        GridLinesVisibility="Vertical"
                        CanUserAddRows="True"
                        CanUserDeleteRows="True"                            
                        x:Name="GridItems"
                        Margin="20,5,5,5">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn Header="Items">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding Items.StrDescripcionConcepto}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                            <DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <!--
                                        Here is my problem How can i to bind to the propper values to perform Editing 
                                        Without having this exception "TWO WAY BINDING REQUIRES PATH OR XPATH"  when try to update DETAIL items:
                                    -->     
                                    <TextBox Text="{Binding Items.StrDescripcionConcepto}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellEditingTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Grid>
</Window>

Now, I need help on how to build a propper CellEditingTemplate, to allow me edit all the changes that i need ? 现在,我需要有关如何构建适当的CellEditingTemplate的帮助,以允许我编辑所需的所有更改?

Here is my problem How can i to bind to the propper values to perform Editing Without having this exception "TWO WAY BINDING REQUIRES PATH OR XPATH" when try to update DETAIL items? 这是我的问题,当尝试更新详细项目时,如何在没有异常“ TWO WAY BINDING REQUIRES PATH或XPATH”的情况下绑定到适当的值以执行编辑?

NOTE: I don't want to create new Items , here, Just attach it to Detail 注意:我不想在这里创建新项目 ,只需将其附加到详细信息

Finally found my problem and of course the solution. 终于找到了我的问题,当然也找到了解决方案。

The binding must be relative to the datacontext of the window instead relative to it's parent, in this case DataGrid 绑定必须相对于窗口的数据上下文,而不是对于其父窗口,在这种情况下为DataGrid

I'm redefining the datacontext of the window as a static resource, then I reuse it for my elements that need access to the global properties of my model, Grid and CellEditingTemplate 我将窗口的数据上下文重新定义为静态资源,然后将其重用于需要访问模型的全局属性Grid和CellEditingTemplate的元素

<Window.Resources>
    <ViewModels:ViewModel x:Key="ViewDataContext"/>
</Window.Resources>

<!-- Here I use Static resource as Data context -->
<Grid DataContext="{Binding Source={StaticResource ResourceKey=ViewDataContext}}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Tipo de asociado" x:Name="TipoUsuarioSeleccionado">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding SomeElement}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                   <DataTemplate>
                     <!-- Again I use Static resource as Data context -->
                     <Grid Height="130" DataContext="{Binding Source={StaticResource ViewDataContext}}">
                           <Grid.RowDefinitions>
                               <RowDefinition Height="Auto"></RowDefinition>
                               <RowDefinition Height="*"></RowDefinition>
                           </Grid.RowDefinitions>
                           <TextBox x:Name="Filtro" Text="{Binding SomeInViewModel}"/>
                           <ListView Grid.Row="1" ItemsSource="{Binding ListaItems}">
                              <ListView.ItemTemplate>
                                  <DataTemplate>
                                     <TextBlock Text="{Binding SomeinVM}"/>
                                  </DataTemplate>
                              </ListView.ItemTemplate>
                           </ListView>
                     </Grid>
                </DataTemplate>
             </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
</Grid>

The error, "TWO WAY BINDING REQUIRES PATH OR XPATH", can also be thrown if your binding path is incorrect. 如果您的绑定路径不正确,也可能引发错误“双向绑定路径或XPATH”。 For example, if your property is called "DisplayName", but you have used "Name" in the XAML binding expression. 例如,如果您的属性名为“ DisplayName”,但是您在XAML绑定表达式中使用了“名称”。

In this case, you will also get additional information from the VS debugger in the Output window if you're looking for it. 在这种情况下,如果需要,您还将在“输出”窗口中从VS调试器中获取其他信息。 Or, if like me, you don't remember to look there, maybe you'll spend half a day scouring the internet before realizing you made a assumption followed by a typo. 或者,如果像我一样,您不记得去那里看了,也许您会花半天的时间在互联网上进行搜索,然后才意识到自己做了一个假设,然后再打错字。

So in my case, this error meant that the binding path was incorrect. 因此,就我而言,此错误意味着绑定路径不正确。 Perhaps your Path is missing and you need to specify it (hence, the abundance of Binding Path=. vs. Binding advice). 也许您的路径丢失了,您需要指定它(因此, Binding Path=. Binding Binding Path=. Binding建议的数量很多)。 Or perhaps you made a typo and need to double check your assumptions regarding property names. 或者,也许您打错了字,并且需要仔细检查关于属性名称的假设。

Rule #1 with WPF binding debugging. 使用WPF绑定调试的规则#1。 Keep that Output window open at ALL times. 始终保持“输出”窗口处于打开状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM