WPF, property in ValidationRule never set

我与影子孤独终老i 提交于 2019-12-14 03:14:30

问题


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<CheckboxViewModel> 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); }
    }
}

回答1:


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




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/3577899/wpf-property-in-validationrule-never-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!