将列表框中的选定项与datatemplate绑定

时间:2016-03-31 20:10:31

标签: c# wpf mvvm

我有一个问题和答案ListBox正在从Database获取数据。现在我想显示或编辑“列表框”中所选行的数据,但我有问题如何到达此行。

编辑。图像显示我想要做的事情: http://imgur.com/5NHjYA4

我的观点:

<Window x:Class="QuizMaker.MainWindow"
    <Window.DataContext>
        <local:MainViewModel />
    </Window.DataContext>

    <Window.Resources>
        <DataTemplate x:Key="QuestionsTemplate">
            <Grid>      
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="320" />
                    <ColumnDefinition Width="120" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="20" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Path=Question}" FontWeight="Bold" />
                <TextBlock Grid.Column="1" Text="{Binding Path=AnswerA}" />
                <TextBlock Grid.Column="2" Text="{Binding Path=AnswerB}"/>
                <TextBlock Grid.Column="3" Text="{Binding Path=AnswerC}"/>
                <TextBlock Grid.Column="4" Text="{Binding Path=AnswerD}"/>
                <TextBlock Grid.Column="5" Text="{Binding Path=RightAnswer}" FontWeight="Bold"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>

    <Grid>        
        <ListBox  DataContext="{Binding MyDataSet}" 
                  x:Name="listBox"   
                  ItemsSource="{Binding Path=QuestionTable}"
                  ItemTemplate="{StaticResource QuestionsTemplate}" 
                  SelectedItem="{Binding SelectedItemString}"             
        />

    </Grid>
</Window>

ViewModel(我剪掉了大部分属性)

{
    class MainViewModel
    {
        private string _appPath;

        private MainModel _MainModel;


        public MainViewModel()
        {
            _MainModel = new MainModel();


            mdbFile = Path.Combine(AppDataPath, "QuestionBase.mdb");
            connString = $"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={mdbFile}";
            conn = new OleDbConnection(connString);

            adapter = new OleDbDataAdapter("SELECT * FROM QuestionTable;", conn);

            MyDataSet = new DataSet();
            adapter.Fill(MyDataSet, "QuestionTable");


        }

        private void AddToDB()
        {
            conn.Open();
            OleDbCommand myCommand = new OleDbCommand("Insert INTO QuestionTable ( Question, AnswerA, AnswerB, AnswerC, AnswerD ) Values(@Question, @AnswerA, @AnswerB, @AnswerC, @AnswerD)", conn);
            myCommand.Parameters.Add("@Question", OleDbType.BSTR).Value = Question;
            myCommand.Parameters.Add("@Question", OleDbType.BSTR).Value = AnswerA;
            myCommand.Parameters.Add("@Question", OleDbType.BSTR).Value = AnswerB;
            myCommand.Parameters.Add("@Question", OleDbType.BSTR).Value = AnswerC;
            myCommand.Parameters.Add("@Question", OleDbType.BSTR).Value = AnswerD;
            myCommand.ExecuteNonQuery();
            conn.Close();
        }

        private string AppDataPath
        {
            get
            {
                if (string.IsNullOrEmpty(_appPath))
                {
                    _appPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                }
                return _appPath;
            }
        }

        public OleDbDataAdapter adapter
        {
            get
            {
                return _MainModel.adapter;
            }
            set
            {
                _MainModel.adapter = value;
                OnPropertyChanged("adapter");
            }
        }
        public DataSet MyDataSet
        {
            get
            {
                return _MainModel.MyDataSet;
            }
            set
            {
                _MainModel.MyDataSet = value;
                OnPropertyChanged("MyDataSet");
            }
        }
    public string SelectedItemString
    {
        get
        {
            return _MainModel.SelectedItemString;
        }
        set
        {
            _MainModel.SelectedItemString = value;
            OnPropertyChanged("SelectedItemString");
        }
    }


        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }





    }
}

2 个答案:

答案 0 :(得分:0)

抱歉,我无法添加评论。我希望您的要求是在TextBox中显示所选项的值,并在从TextBox更改值时将相同的值更新到您的集合中(在您的情况下为DataTable)。如果这是您的要求,请更改像这样的TextBox绑定

<TextBox x:Name="ValueText" Text="{Binding SelectedItem.ColumnName, ElementName=listBox, UpdateSourceTrigger=PropertyChanged}" />

我不知道为什么要将SelectedItem绑定到字符串类型SelectedItemString属性。它会根据您的来源创建绑定错误。

答案 1 :(得分:0)

SelectedItemString属性更改为DataRow,并将其他控件绑定到该属性。

例如,

public DataRow SelectedItem
{
    get
    {
        return _MainModel.SelectedItem;
    }
    set
    {
        _MainModel.SelectedItem = value;
        OnPropertyChanged("SelectedItem");
    }
}

在XAML中应该是这样的:

<Window x:Class="QuizMaker.MainWindow"
    <Window.DataContext>
        <local:MainViewModel />
    </Window.DataContext>

    <Window.Resources>
        <DataTemplate x:Key="QuestionsTemplate">
            <Grid>      
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="320" />
                    <ColumnDefinition Width="120" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="20" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Path=Question}" FontWeight="Bold" />
                <TextBlock Grid.Column="1" Text="{Binding Path=AnswerA}" />
                <TextBlock Grid.Column="2" Text="{Binding Path=AnswerB}"/>
                <TextBlock Grid.Column="3" Text="{Binding Path=AnswerC}"/>
                <TextBlock Grid.Column="4" Text="{Binding Path=AnswerD}"/>
                <TextBlock Grid.Column="5" Text="{Binding Path=RightAnswer}" FontWeight="Bold"/>
            </Grid>
        </DataTemplate>
    </Window.Resources>

    <DockPanel>   
        <ContentControl Content="{Binding SelectedItem}" 
                        ContentTemplate="{StaticResource QuestionsTemplate}" 
                        DockPanel.Dock="Top" />  

        <ListBox  DataContext="{Binding MyDataSet}" 
                  x:Name="listBox"   
                  ItemsSource="{Binding Path=QuestionTable}"
                  ItemTemplate="{StaticResource QuestionsTemplate}" 
                  SelectedItem="{Binding SelectedItem}"             
        />

    </DockPanel>
</Window>

此外,如果您真的不想改变跟踪所选项目的方式,您也可以直接绑定listBox.SelectedItem Davys said

<ContentControl Content="{Binding ElementName=listBox, Path=SelectedItem}" 
                ContentTemplate="{StaticResource QuestionsTemplate}" 
                DockPanel.Dock="Top" />