开发者

WPF, property in ValidationRule never set

I'm trying to bind a property in my DataContext to a property in a ValidationRule:

public class ReleaseValidationRule : ValidationRule
{
    // I want to bind a value from my DataContext to this property:
    public CheckboxViewModels ValidReleases { get; set; }
    ...
}

Based on this thread, I created the CheckboxViewModels class just to act as a wrapper for a List<Chec开发者_如何学编程kboxViewModel> so that the list could be a DependencyProperty so that I could bind to it. However, in my Validate method on my ValidationRule, the ValidReleases list is always empty. Here's my XAML:

<TextBox>
    <TextBox.Text>
        <Binding Path="Release" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:ReleaseValidationRule>
                    <local:ReleaseValidationRule.ValidReleases>
                        <local:CheckboxViewModels List="{Binding Path=Releases,
                            Converter={StaticResource debugConverter}}"/>
                    </local:ReleaseValidationRule.ValidReleases>
                </local:ReleaseValidationRule>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

I know the Releases property (what I'm binding to the List property of CheckboxViewModels) has content because I have a TreeView just above the TextBox that shows the contents of Releases. The converter I have on the CheckboxViewModels.List binding does nothing, it's just a place where I can set a breakpoint. The funny thing is, that converter breakpoint never gets hit. It's as if the whole line <local:CheckboxViewModels List="{Binding Path=Releases, Converter={StaticResource debugConverter}}"/> never gets executed, so the ValidReleases property in my ValidationRule never gets set. What's going on?

Edit: here's what CheckboxViewModels looks like:

public class CheckboxViewModels : DependencyObject, IList<CheckboxViewModel>,
    IEnumerable<CheckboxViewModel>
{
    ...members necessary to implement IList, IEnumerable...

    public static readonly DependencyProperty ListProperty =
        DependencyProperty.Register(
            "List",
            typeof(List<CheckboxViewModel>),
            typeof(CheckboxViewModels),
            new PropertyMetadata(new List<CheckboxViewModel>())
        );

    public List<CheckboxViewModel> List
    {
        get { return (List<CheckboxViewModel>)GetValue(ListProperty); }
        set { SetValue(ListProperty, value); }
    }
}


Smells like a missing Property Changed notification somewhere. Hard to see what CheckboxModels is about from this, but if it were ObservableCollection you'd get property changed without any extra work. Does this make sense?

HTH,
Berryl


Okay, now I just feel silly. I had had a constructor in CheckboxViewModels that set List = new List<CheckboxViewModel>(). I think this was somehow resetting something? I removed that constructor and the initial value of List is set only in the Register method for the DependencyProperty: new PropertyMetadata(new List<CheckboxViewModel>()). ValidReleases is now populated as expected with the following XAML:

<TextBox>
    <TextBox.Text>
        <Binding Path="Release" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:ReleaseValidationRule ValidatesOnTargetUpdated="True">
                    <local:ReleaseValidationRule.ValidReleases>
                        <local:CheckboxViewModels
                            List="{Binding Path=Releases, Mode=OneWay}"/>
                    </local:ReleaseValidationRule.ValidReleases>
                </local:ReleaseValidationRule>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Edit: not so silly afterall: not having a constructor in CheckboxViewModels resulted in two dependency properties of type CheckboxViewModels using the same list, so I had releases and other data in both the Releases property and another property. Adding the constructor back to CheckboxViewModels results in ValidReleases not having any items again. I think I must be binding something incorrectly.


I stopped using validation rules and instead followed this tutorial about implementing IDataErrorInfo. That was my class instance is fully initialized by the time I get into this[string] to figure out the error message. The data I had been trying to pass in was just data from another property on the same instance. That is, I wanted to validate Property1 using some data from Property2. With IDataErrorInfo, when I'm validating Property1 and assembling an error message if necessary, I have access to Property2 as desired, without having to pass anything in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜