2015-08-10 5 views
0

Я создал (немного) Увеличенная Checkbox, который имеет свойство ISERROR (в основном используется для изменения цвета флажка на красный, когда какое-либо условие не выполняется) следующим образом:Отображение Настраиваемая в ItemsControl

public class MyCheckBox : CheckBox 
{ 
    public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(MyCheckBox), new UIPropertyMetadata(false)); 

    public MyCheckBox() : base() 
    { 
     IsError = false; 
     IsCorrect = false; 
    } 

    public bool IsError 
    { 
     get { return (bool)GetValue(IsErrorProperty); } 
     set { SetValue(IsErrorProperty, value); } 
    } 
} 

Этот элемент управления связан со следующим стилем:

<Style TargetType="{x:Type local:MyCheckBox}"> 
    <Setter Property="FontSize" Value="14"/> 
    <Setter Property="VerticalContentAlignment" Value="Center"/> 
    <Setter Property="Margin" Value="0,2,8,2"/> 
    <Setter Property="BorderBrush" Value="Yellow"/> 
    <Setter Property="BorderThickness" Value="2"/> 
    <Style.Triggers> 
     <Trigger Property="IsEnabled" Value="False"> 
      <Setter Property="Foreground" Value="LightGray"/> 
      <Setter Property="BorderThickness" Value="0"/> 
     </Trigger> 
     <Trigger Property="IsError" Value="True"> 
      <Setter Property="BorderBrush" Value="Red"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

Все хорошо, если я создаю один из этих флажков на это реагирует на IsError правильно переплета.

Проблема, с которой я сталкиваюсь, заключается в размещении их внутри элемента ItemsControl. Если я создаю элемент управления очень элементарных элементов и вручную устанавливаю значения, то он работает - отображается список элементов, а свойства IsError и IsChecked действуют так, как ожидалось.

<ItemsControl Grid.Column="3" Grid.Row="8" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0"> 
    <local:MyCheckBox Content="Item1"/> 
    <local:MyCheckBox Content="Item2" IsChecked="True"/> 
    <local:MyCheckBox Content="Item3" IsError="True"/> 
    <local:MyCheckBox Content="Item4" IsChecked="True" IsError="True"/> 
</ItemsControl> 

Если, однако я использую привязки для списка элементов тогда содержание и IsChecked свойства работают, как и ожидалось, но свойство IsError полностью игнорируется, я не могу получить границы для изменения на красный.

<ItemsControl Grid.Column="3" Grid.Row="8" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0"> 
       ItemsSource="{Binding MyThings}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <local:MyCheckBox Content="{Binding Path=ColorName}" IsChecked="{Binding Path=IsPresent}" IsError="{Binding Path=IsError}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Я знаю, что связывание значения IsError правильно (я тестировал, включив ярлык, связанный с тем же значением, которое отображается правильный True/False информации), но я не могу работать, как получить настроенную Checkbox для отображения должным образом; это как если бы отображаемый элемент использовал стандартный флажок вместо настраиваемой версии.

Для справки, список элементов управления связан следующим образом:

public class Thing : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged 
    protected void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 

    private string colorName; 
    public string ColorName 
    { 
     get { return colorName; } 
     set { colorName = value; RaisePropertyChanged("ColorName"); } 
    } 

    private bool isPresent; 
    public bool IsPresent 
    { 
     get { return isPresent; } 
     set { isPresent = value; RaisePropertyChanged("IsPresent"); } 
    } 

    private bool isError; 
    public bool IsError 
    { 
     get { return isError; } 
     set { isError = value; RaisePropertyChanged("IsError"); } 
    } 

    public CastorClip(string colorName) 
    { 
     ColorName = colorName; 
     IsPresent = false; 
     IsError = false; 
    } 
} 

private ObservableCollection<Thing> myThings = new ObservableCollection<Thing>(); 
public ObservableCollection<Thing> MyThings 
{ 
    get { return myThings; } 
    set { myThings = value; RaisePropertyChanged("MyThings"); } 
} 

Что мне не хватает? Как я могу сделать эту работу?

ответ

0

Оказалось, что это была проблема в конструкторе пользовательского флажка, где было установлено свойство IsError, переписывающее выражение привязки. Я также позволю другим возможностям, чтобы другие люди, которые попали в эти общие ловушки WPF, могли сразу их проверить.

Свойства IsError не связаны два пути по умолчанию, измените:

new UIPropertyMetadata(false) 

к:

new FrameworkPropertyMetadata { 
    BindsTwoWayByDefault = true, 
    DefaultValue = false 
} 

Кроме того, добавьте в статический конструктор флажка так, что он будет стремиться стиль по умолчанию, соответствующий вашему флажку:

static MyCheckBox() 
{ 
    DefaultStyleKeyProperty.OverrideMetadata (typeof (MyCheckBox), new FrameworkPropertyMetadata (typeof (MyCheckBox))); 
} 

Обязательно проверьте, как ресурс является b eing добавлен в ваше приложение.

+0

Я попытался изменить IsError на использование двухсторонней привязки по умолчанию, как указано выше, и, изменив режим на TwoWay в XAML, но нет изменений, значение переходит к ItemsControl (я могу видеть значение по используя ярлык), но триггер на MyCheckBox, похоже, не вызван. – timrorr

+0

Да, он не распознает пользовательский стиль как стандартный по умолчанию, также не забудьте проверить, как стиль добавляется в ресурсы приложения. –

+0

Если я добавлю статический конструктор, то CheckBoxes вообще не будут отображаться.Я обнаружил, что если я изменил значение IsError внутри обработчика события, связанного с этим флажком, произойдет событие ошибки (я установил значение IsError непосредственно из события Checked и очистил событие Unchecked), но если я сделаю измените на IsError из кода viewmodel, тогда ничего не произойдет. – timrorr