如果通过Reflection设置视图模型属性,则WPF绑定不起作用

时间:2011-12-30 12:55:48

标签: c# wpf xaml binding converter

我正在尝试构建一个显示进度条的页面,直到从服务器成功下载数据为止。

为此我使用通用数据下载器,它只是填充模型的属性并将IsLoading属性设置为true和/或false

View模型如下所示:

public class GenericPageModel: GenericModel
{
    private bool _isLoading;
    public bool IsLoading
    {
        get { return _isLoading; }
        set
        {
            _isLoading = value;
            OnPropertyChanged("IsLoading");
        }
    }
}

public class GenericModel :  INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

GenericPageModel在XAML页面中用作模型,IsLoading属性用作如下:

<Grid>
    <Grid.Resources>
        <BooleanToVisibilityConverter x:Key="boolToVis"/>            
    </Grid.Resources>
    <ProgressBar Height="25" Margin="5"
                 VerticalAlignment="Center" HorizontalAlignment="Stretch"
                 Visibility="{Binding IsLoading, Converter={StaticResource boolToVis}}"
                 IsIndeterminate="True"
    />
</Grid>

通用数据下载器:

...
// Model that it's calling this
public object Model
{ get; set; }

private string _loadingProperty;
...

void _bw_DoWork(object sender, DoWorkEventArgs e)
{
    // Set the is loading property
    if (null != _loadingProperty)
    {
        //((Model as GenericModel).Owner as GenericPageModel).IsLoading = true;  // Works!!
        Model.GetType().GetProperty(_loadingProperty).SetValue(Model, true, null); // Doesn't work
    }
 }

如果我明确地将Model转换为GenericPageModel并将IsLoading设置为true,那么一切正常(请参阅注释行)

如果我使用反射来设置属性的值,则正确命中IsLoading setter,将OnPropertyChanged方法称为ok,但UI不会更新

通过反射设置属性时是否还需要做一些额外的事情?我猜测事件没有正确提出,但我无法弄清楚要做什么。

解决了在下载程序调用之前插入了一个额外的模型,该行应该说:

object Owner = Model.GetType().GetProperty("Owner").GetValue(Model, null);               
Model.GetType().GetProperty(_loadingProperty).SetValue(Owner, true, null);

1 个答案:

答案 0 :(得分:3)

以下行

((Model as GenericModel).Owner as GenericPageModel).IsLoading = true;  // Works!!
Model.GetType().GetProperty(_loadingProperty).SetValue(Model, true, null); // Doesn't work

不等同。第一个影响IsLoading对象上的Model.Owner属性,第二个影响Model对象本身。

注意:您的ViewModel基类实际上不应该被称为GenericModel,因为它是ViewModel,而不是模型。