双向绑定无法正常工作

时间:2012-01-11 22:41:14

标签: wpf mvvm datagrid

我正在使用WPF MVVM Pattern。我的视图中有2个ListBoxes和一个DataGrid。我正在使用EntityFramework从SQL Server获取数据。我的ViewModel看起来像这样

    private Types _type;
    private Users _user;
    private ObjectResult<APP> _dataContext;

    public IEnumerable<Types> Categories
    {
        get;
        private set;
    }

    public IEnumerable<Users> SystemNames
    {
        get;
        private set;
    }

    public Types SelectedType
    {
        get
        {
            return _type;
        }
        set
        {
            _type = value;
            RaisePropertyChanged("SelectedType");
        }
    }       

    public Users SelectedUser
    {
        get
        {
            return _user;
        }
        set
        {
            _user = value;
            RaisePropertyChanged("SelectedUser");
        }
    }

    public ObjectResult<APP> DContext
    {
        get
        {
            return _dataContext;
        }
        set
        {
            _dataContext = value;
            RaisePropertyChanged("DContext");
        }
    }

    public ObjectResult<APP> GetDataContext()
    {
        AppLogEntities context = new AppLogEntities();
        return context.GetAppLog(SelectedUser.User, SelectedType.Type);
    }

    public DetailsViewModel()
    {
        Categories = new List<Types>
        {
            new Types{Type = "All"},
            new Types{Type = "Information"},
            new Types{Type = "Warning"},
            new Types{Type = "Error"}
        };

        SystemNames = new List<Users>
        {
            new Users{User = "All"},
            new Users{User = "SYS_01"},
            new Users{User = "SYS_02"}
        };

        SelectedType = new Types();
        SelectedUser = new Users();

        DContext = GetDataContext();
    }`

我的观点就像这样

<Window x:Class="SingleAppLogMVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:SingleAppLogMVVM"
    Title="MainWindow" Height="800" Width="1000">
<Window.DataContext >
    <vm:DetailsViewModel />
</Window.DataContext>
<Grid>
    <ListBox Height="200" HorizontalAlignment="Left" Margin="50,50,0,0" Name="fTypeListBox" VerticalAlignment="Top" Width="125" SelectionMode="Single" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Categories}" SelectedItem="{Binding SelectedType, Mode=TwoWay}" >
        <ListBox.ItemTemplate >
            <DataTemplate >
                <DockPanel Width="120" LastChildFill="True" >
                    <TextBlock Text="{Binding Type, Mode=TwoWay}" Width="110" Margin="5" />
                </DockPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ListBox Height="Auto" HorizontalAlignment="Left" Margin="50,275,0,50" Name="fUserListBox" VerticalAlignment="Stretch" Width="125" SelectionMode="Single" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding SystemNames}" SelectedItem="{Binding SelectedUser, Mode=TwoWay}"  >
        <ListBox.ItemTemplate >
            <DataTemplate >
                <DockPanel Width="120" LastChildFill="True" >
                    <TextBlock Text="{Binding User, Mode=TwoWay}" Width="110" Margin="5" />
                </DockPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <DataGrid AutoGenerateColumns="False" Height="350" HorizontalAlignment="Stretch" Margin="225,50,50,0" IsReadOnly="True" Width="Auto"
              VerticalAlignment="Top" CanUserReorderColumns="False" CanUserResizeColumns="False" Name="fDGrid"  VirtualizingStackPanel.IsVirtualizing="True"
              CanUserResizeRows="False" IsManipulationEnabled="True" RowHeight="35" SelectionMode="Single" VirtualizingStackPanel.VirtualizationMode="Recycling"
              ItemsSource="{Binding DContext, Mode=OneWay}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" Width="5*" />
            <DataGridTextColumn Header="IID" Binding="{Binding Path=IID}" Width="5*" />
            <DataGridTextColumn Header="INSTANCEID" Binding="{Binding Path=INSTANCEID}" Width="10*" />
            <DataGridTextColumn Header="TYPE" Binding="{Binding Path=TYPE}" Width="10*" />
            <DataGridTextColumn Header="SOURCE" Binding="{Binding Path=SOURCE}" Width="10*" />
            <DataGridTextColumn Header="TIME" Binding="{Binding Path=TIME}" Width="10*" />
            <DataGridTextColumn Header="SNAME" Binding="{Binding Path=SNAME}" Width="10*" />
            <DataGridTextColumn Header="MESSAGE" Binding="{Binding Path=MESSAGE}" Width="15*" />
            <DataGridTextColumn Header="ACTIONS" Binding="{Binding Path=ACTIONS}" Width="15*" />
            <DataGridTextColumn Header="CLEARED ON" Binding="{Binding Path=CLEAREDON}" Width="10*" />
        </DataGrid.Columns>
    </DataGrid>        
</Grid>

我可以填充我的LisBoxes。如果在我的ViewModel代码中手动设置插件值,我也可以填充我的DataGrid

 public ObjectResult<APP> GetDataContext()
    {
        AppLogEntities context = new AppLogEntities();
        return context.GetAppLog(SelectedUser.User, SelectedType.Type);
    }

我不明白为什么它根据我从ListBoxes的选择不起作用。请帮帮我。

2 个答案:

答案 0 :(得分:1)

每次在viewmodel中更改GetDataContext()SelectedUser属性时,您都需要手动调用SelectedType。属性设置器是一种很好的方法 - 尽管如果GetDataContext()是一个长时间运行的操作,那么你应该异步执行它,这样在加载结果时UI不会冻结。

答案 1 :(得分:1)

需要进行一些小改动才能获得

之后的结果
public Types SelectedType
{
    get
    {
        return _type;
    }
    set
    {
        _type = value;
        RaisePropertyChanged("SelectedType");
        DContext = GetDataContext(); //refresh the data
    }
}       

public Users SelectedUser
{
    get
    {
        return _user;
    }
    set
    {
        _user = value;
        RaisePropertyChanged("SelectedUser");
        DContext = GetDataContext(); //refresh the data
    }
}


public DetailsViewModel()
{
    Categories = new List<Types>
    {
        new Types{Type = "All"},
        new Types{Type = "Information"},
        new Types{Type = "Warning"},
        new Types{Type = "Error"}
    };

    SystemNames = new List<Users>
    {
        new Users{User = "All"},
        new Users{User = "SYS_01"},
        new Users{User = "SYS_02"}
    };

    _type = new Types();  //use the field rather than the property so GetDatacontenxt doesnt get called multiple times
    _user = new Users();
    DContext = GetDataContext();
}