Member Avatar for pilsdumps

Hi,

Just learning WPF and I wondered if there's an easy way to amend a controls control template with c# code?

To explain - I'm using two 'types' of validation - one to ensure the data conforms to the requirements of an underlying table, and another to ensure the data conforms to another set of rules. The validations are applied dynamically as required, but I can't figure out how to change the error template.

The first validation uses this;

<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBoxBase}">
    <Setter Property="Margin" Value="2" />
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="MinWidth" Value="120"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="AllowDrop" Value="true"/>

    <!--ERROR TEMPLATE-->
    <Setter Property="Validation.ErrorTemplate">
      <Setter.Value>
        <ControlTemplate>
          <DockPanel LastChildFill="True">
            <Border BorderBrush="Purple" BorderThickness="2" CornerRadius="4,4,4,4" SnapsToDevicePixels="True" >
              <AdornedElementPlaceholder />
            </Border>
          </DockPanel>                            
        </ControlTemplate>
      </Setter.Value>
    </Setter>

Can someone tell me how to create the equivalent in C# code, and then I can amend as required and reapply it for the second validation.

Thanks

Member Avatar for pilsdumps

Thought I'd answer my own thread in case anyone is interested....

It's fairly simple;

I have 2 controltemplates defined in resources;

<ControlTemplate x:Key="temp__">
    <DockPanel LastChildFill="True">
      <Border BorderBrush="Orange" BorderThickness="2" CornerRadius="4,4,4,4" SnapsToDevicePixels="True" >
        <AdornedElementPlaceholder />
      </Border>
    </DockPanel>
  </ControlTemplate>

  <ControlTemplate x:Key="recControl">
    <DockPanel LastChildFill="True">
      <Border BorderBrush="Purple" BorderThickness="2" CornerRadius="4,4,4,4" SnapsToDevicePixels="True" >
        <AdornedElementPlaceholder />
      </Border>
    </DockPanel>
  </ControlTemplate>

I have a class that contains the validations to apply;

public class ValApply
  {
    private DependencyObject m_TargetObject;
    private DependencyProperty m_TargetProperty;    
    private ValidationRule m_ValRule;
    private ControlTemplate m_ControlTemplate;

....

and a helper class to manage the validation

public class PageValidations
  {
    private Page m_pageapply;
    private List<ValApply> temp_valapply = new List<ValApply>();
    private List<ValApply> recControl_valapply = new List<ValApply>();

.....

then using this method,

/// <summary>
    /// Applies and validates the recControl validations 
    /// </summary>
    /// <returns>True if the applied recControl validations are passed</returns>
    public bool ValidateRecControlVals()
    {
      bool retResult = true;

      //iterate the recControl validations
      foreach (ValApply recval in recControl_valapply)
      {
        //test if a recControl val and apply it if so
        if (((ValidationBase)recval.ValRule).ValidationType == ValidationType.recControl)
        {
          Binding bind = BindingOperations.GetBinding(recval.TargetObject, recval.TargetProperty);
          bind.ValidationRules.Clear();         
          bind.ValidationRules.Add(recval.ValRule);

          //get the expression for checking
          BindingExpression expression = BindingOperations.GetBindingExpression(recval.TargetObject, recval.TargetProperty);

          //clear existing invalid as may change when new rules applied
          System.Windows.Controls.Validation.ClearInvalid(expression);

          //mark any invalid
          ValidationResult result = recval.ValRule.Validate(recval.TargetObject.GetValue(recval.TargetProperty), null);
          if (!result.IsValid)
          {
            //add the error template and show it
            Validation.SetErrorTemplate(recval.TargetObject, recval.ControlTemp);
            System.Windows.Controls.Validation.MarkInvalid(expression, new ValidationError(recval.ValRule, expression, result.ErrorContent, null));
            retResult = false;
          }
        }
      }

      return retResult;
    }

existing validations are cleared, the validation rule is applied and the new content template applied.

I like XAML for simple markup and design, but for more complicated procedures and applying dynamic settings, it seems code is easier. Also, this method means that all validations can be applied in one place (construction of the page) which simplifies amendments and saves hunting through markup.
Ta.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.