WPF vinculação de dados usando IMultiValueConverter e lançando erros
-
16-09-2019 - |
Pergunta
Como parte da aprendizagem WPF Eu trabalho apenas acabado através de um Laboratório Exercício MS "Usando dados de vinculação no WPF" ( http://windowsclient.net/downloads/folders/hands-on-labs/entry3729.aspx ).
Para ilustrar usando um IMultiValueConverter, há uma aplicação pré-codificada de um em que o resultado booleana é usado para determinar se a ligação de dados é relevante para o utilizador actual. Aqui está o código para a operação de conversão:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
// var rating = int.Parse(values[0].ToString());
var rating = (int)(values[0]);
var date = (DateTime)(values[1]);
// if the user has a good rating (10+) and has been a member for more than a year, special features are available
return _hasGoodRating(rating) && _isLongTimeMember(date);
}
E aqui é a fiação de usar isso no XAML:
<ComboBox.IsEnabled>
<MultiBinding Converter="{StaticResource specialFeaturesConverter}">
<Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
<Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
</MultiBinding>
</ComboBox.IsEnabled>
O código funciona muito bem, mas o designer XAML não será carregado com um "cast especificado não é válido." erro. Eu tentei um par de maneiras para não usar um elenco, um dos quais eu deixei comentada no código acima. O engraçado é um exercício de laboratório acabado fornecido pela MS também tem o erro.
Alguém sabe como consertá-lo para fazer o designer feliz?
Cheers,
Berryl
Solução
O problema aqui é que você use Application.Current, que é diferente no modo de design e em tempo de execução.
Quando você desenhador aberto, Application.Current não será sua classe "App" (ou qualquer o nome dele). Assim, há nenhuma propriedade CurrentUser lá, e seu get esse erro.
Existem várias maneiras de corrigi-lo. O mais fácil é verificar se você está em modo de design:
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (Application.Current == null ||
Application.Current.GetType() != typeof(App))
{
// We are in design mode, provide some dummy data
return false;
}
var rating = (int)(values[0]);
var date = (DateTime)(values[1]);
// if the user has a good rating (10+) and has been a member for more than a year, special features are available
return _hasGoodRating(rating) && _isLongTimeMember(date);
}
Outra abordagem seria não usar Application.Current como uma fonte para a sua ligação.
Espero que isso ajude:).