2014-02-27 14 views
5

Ich arbeite an einem LightSwitch-Steuerelement, das in der Lage ist (zumindest ist dies beabsichtigt ...), verschiedene unterschiedliche Eigenschaften basierend auf einem diskriminierenden Wert zu binden und zu bearbeiten.Warum ist meine benutzerdefinierte Steuerung immer schreibgeschützt?

Lassen Sie mich ein wenig weiter erklären. Die Tabelle sieht wie folgt aus: enter image description here

, nun basierend auf dem Wert von Datenformat, die Steuerung selbst dynamisch an ErgebnisBool, ErgebnisDatum bindet und so weiter und wählt die entsprechende DataTemplate aus der Kontrolle des xaml. ErgebnisAnzeige ist eine berechnete Texteigenschaft, die eine schreibgeschützte Anzeigestring enthält.

XAML Kontrolle ist wie folgt:

<UserControl x:Class="EuvControlsExtension.Presentation.Controls.ProzessErgebnisEdit" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:framework ="clr-namespace:Microsoft.LightSwitch.Presentation.Framework;assembly=Microsoft.LightSwitch.Client" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    xmlns:ct="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" 
    xmlns:multi="clr-namespace:EuvControlsExtension.Presentation.Controls" 
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" 
    mc:Ignorable="d" 
    x:Name="HostControl"> 

    <multi:MtTemplateSelector x:Name="MyTemplateSelector" 
          Content="{Binding Path=RootEntity, Mode=TwoWay, ElementName=HostControl, UpdateSourceTrigger=Default}" 
          HorizontalContentAlignment="Stretch" 
          VerticalContentAlignment="Center" 
          IsHitTestVisible="False"> 

     <!--Zahl--> 
     <multi:MtTemplateSelector.ZahlTemplate> 
      <DataTemplate> 
       <TextBox HorizontalAlignment="Stretch" 
       Text="{Binding Path=RootEntity.ErgebnisZahl, ElementName=HostControl, Mode=TwoWay, UpdateSourceTrigger=Default, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/> 
      </DataTemplate> 
     </multi:MtTemplateSelector.ZahlTemplate> 

     <!--Bool--> 
     <multi:MtTemplateSelector.BoolTemplate> 
      <DataTemplate> 
       <CheckBox IsThreeState="True" 
       Content="{Binding Path=RootEntity.ErgebnisBool, ElementName=HostControl, Mode=TwoWay, UpdateSourceTrigger=Default, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/> 
      </DataTemplate> 
     </multi:MtTemplateSelector.BoolTemplate> 

    </multi:MtTemplateSelector> 
</UserControl> 

Die MtTemplateSelector Klasse gibt einfach die entsprechende Datatemplate für das aktuelle Format, wir haben hier nichts Besonderes.

Die Steuerung selbst (ProzessErgebnisEdit) ist auch sehr einfach. Es tut nichts, als die Entitätsinstanz Bindung (genannt RootEntity):

public partial class ProzessErgebnisEdit : UserControl 
{ 
    public ProzessErgebnisEdit() 
    { 
     InitializeComponent(); 
     BindProperties(); 
    } 

    private void BindProperties() 
    { 
     var binding = new Binding("DataSourceRoot.RootObject") 
          { 
           Mode = BindingMode.TwoWay 
          }; 
     this.SetBinding(RootEntityProperty, binding);   
    } 

    public object RootEntity 
    { 
     get { return GetValue(RootEntityProperty); } 
     set { SetValue(RootEntityProperty, value); } 
    } 

    public static readonly DependencyProperty RootEntityProperty = DependencyProperty.Register(
     "RootEntity", 
     typeof(object), 
     typeof(ProzessErgebnisEdit), 
     new PropertyMetadata(null)); 
} 

Last not least habe ich diese Kontrolle Fabrik haben, die eine Anzeige nur für Datatemplate zurückgibt, wenn angemessen:

[Export(typeof(IControlFactory))] 
[ControlFactory("EuvControlsExtension:ProzessErgebnisEdit")] 
internal class ProzessErgebnisEditFactory : IControlFactory 
{ 
    private DataTemplate dataTemplate; 
    private DataTemplate displayModeDataTemplate; 

    public DataTemplate DataTemplate 
    { 
     get { 
      return this.dataTemplate ?? 
        (this.dataTemplate = XamlReader.Load(ControlTemplate) as DataTemplate); 
     } 
    } 

    public DataTemplate GetDisplayModeDataTemplate(IContentItem contentItem) 
    { 
     return this.displayModeDataTemplate ?? 
       (this.displayModeDataTemplate = XamlReader.Load(DisplayModeControlTemplate) as DataTemplate); 
    } 

    private const string DisplayModeControlTemplate = 
     "<DataTemplate" + 
     " xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" + 
     " <Border Background='GreenYellow'>" + 
     "  <TextBlock Text='{Binding Path=DataSourceRoot.RootObject.ErgebnisAnzeige}' Margin='3' Foreground='Red' " + 
     "    TextAlignment=\"{Binding Properties[Microsoft.LightSwitch:RootControl/TextAlignment]}\"" + 
     "    VerticalAlignment=\"{Binding Properties[Microsoft.LightSwitch:RootControl/VerticalAlignment]}\" />" + 
     " </Border>" + 
     "</DataTemplate>"; 

    private const string ControlTemplate = 
     "<DataTemplate" + 
     " xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"" + 
     " xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"" + 
     " xmlns:ctl=\"clr-namespace:EuvControlsExtension.Presentation.Controls;assembly=EuvControlsExtension.Client\">" + 
     "<ctl:ProzessErgebnisEdit/>" + 
     "</DataTemplate>"; 
} 

Alles funktioniert gut so far: Wenn die Zelle nicht fokussiert ist, erscheint der display-only Text (zB Wahr/Falsch/-), und wenn ich auf klicke, um eine Zelle zu bearbeiten, wird auf das entsprechende DataTemplate (zB eine Checkbox) umgeschaltet. Und es wird immer der korrekte Wert angezeigt, der mir sagt, dass die Datenbindung im Allgemeinen funktioniert.

Das einzige Problem ist, dass die Steuerelemente immer schreibgeschützt sind, und ich bin nicht in der Lage, sie über Code oder XAML oder was auch immer bearbeitbar zu machen.

Bisher habe ich versucht, das Netz der OnPrepareCellEditing Ereignis abfangen und dann manuell false das IsReadOnly Eigentum der jeweiligen Spalte Einstellung, und ich habe auch versucht, das gleiche mit der DataContext.IsReadOnly Eigenschaft Kontrolle. Kein Glück ...

Was vermisse ich? Ist mein gesamter Ansatz fehlerhaft? Was ist denn hier los? Ich kann keinen Grund für dieses Verhalten herauszufinden, ich weiß nicht einmal eine Richtung sehen für die Suche ...

Edit: Auf dem Deutsch Identifikatoren Einige der Identifikatoren in Deutsch und sind somit nicht sein könnten sofort klar für alle. Aber am Ende ist es so einfach: Ergebnis ist Deutsch für Ergebnis. Dieser Ausdruck wird häufig in der Tabelle angezeigt, da der anzuzeigende Wert das Ergebnis eines physischen Produktionsprozesses ist, der verschiedene Datentypen wie bool, string, datetime usw. enthalten kann (nichts Besonderes). Diese Information ist der Inhalt der Spalte Datenformat, die etwas wie DataType in Englisch wäre.

Edit2: Die Vorlage Selektor:

public class MtTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate UnknownTemplate { get; set; } 
    public DataTemplate ZahlTemplate { get; set; } 
    public DataTemplate FreitextTemplate { get; set; } 
    public DataTemplate AuswahlTemplate { get; set; } 
    public DataTemplate BoolTemplate { get; set; } 
    public DataTemplate DatumTemplate { get; set; } 
    public DataTemplate MessungTemplate { get; set; } 
    public DataTemplate DateiPfadTemplate { get; set; } 
    public DataTemplate OrdnerPfadTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     switch (GetDatenFormatEnum(item)) 
     { 
      case DatenformatEnum.Zahl: 
       return ZahlTemplate; 

     ... 
+1

Können Sie versuchen, einige der deutschen (?) Zu übersetzen, denn ohne diese Sprache mit Ihnen zu teilen, ist es sehr schwer, Ihre Absicht und Bedeutung zu verstehen. Tritt das Problem auch bei CheckBoxen und TextBoxen auf? Und was meinst du mit readonly? Dass die IsReadOnly-Eigenschaft True ist oder Ihre Änderungen nicht an dem zugrunde liegenden ViewModel vorgenommen werden? – Zache

+0

@Zache Ich habe die Frage bearbeitet, um eine Erklärung zu den deutschen Kennungen hinzuzufügen. Ich habe auch das oben mit anderen Kontrollen als die oben genannten versucht - immer die gleichen, sie sind deaktiviert. Bezüglich der IsReadOnly-Eigenschaft: Das war einfach ein Tippfehler, natürlich meinte ich 'Falsch'. –

+1

Also ist es IsEnabled = False das ist dein Problem? – Zache

Antwort

2

Sie müssen einfach nur die IsHitTestVisile=False vom multi:MtTemplateSelector dies verhindert, und all seinen Kindern, von immer Ereignisse von Benutzer-Interaktionen entfernen. Sie können mehr erfahren here.

Verwandte Themen