如果视图模型属性是通过反射设置的,那么WPF绑定将不起作用

本文关键字:那么 WPF 绑定 不起作用 设置 反射 模型 视图 属性 如果 | 更新日期: 2023-09-27 18:19:02

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

我使用了一个通用的数据下载器,它将简单地填充模型的属性,并将IsLoading属性设置为true和/或false

视图模型如下:

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不更新

是否有一些额外的东西,需要做的时候设置一个属性通过反射?我猜事件没有正确提出,但我不知道该怎么做。

解决了在downloader调用之前插入了一个额外的模型,这行应该说:

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

如果视图模型属性是通过反射设置的,那么WPF绑定将不起作用

以下行

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

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

注意:你的ViewModel基类真的不应该被称为GenericModel,因为它是ViewModel,而不是模型。