我应该如何只在WPF中选中一个复选框?

时间:2017-08-14 08:50:06

标签: c# wpf

我不太熟悉WPF中的数据绑定。请看一下我的代码。我想限制用户只进行一次选择。

更一般的问题是:我应该如何避免循环遍历数据源,就像我在handleChecked方法中所做的那样?我相信我不需要遍历ItemSource,但不知道如何。

XAML:

<Window x:Class="TheProgram.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="News Chooser">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="9*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
    <Grid Name="newsChooser" Grid.Row="0" Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="8*" />
        </Grid.RowDefinitions>
        <ComboBox Name="newsCategory" Margin="10,8,10,5" Grid.Row="0"/>
        <ComboBox Name="newsSrc" SelectionChanged="handleNewsSrcChange" Margin="10,5,10,8" Grid.Row="1"/>
        <DataGrid SelectionMode="Single" IsReadOnly="True" Margin="10,0,10,8" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="2" Name="newsStories" AutoGenerateColumns="False" RowHeaderWidth="0">
            <DataGrid.Columns>
                <DataGridTextColumn Width="8*" Header="Headline" Binding="{Binding Path=heading}">
                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                    <DataGridTextColumn.ElementStyle>
                        <Style>
                            <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
                            <Setter Property="TextBlock.Padding" Value="5" />
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
                <DataGridCheckBoxColumn Header="Select" Width="2*" Binding="{Binding Path=isIncluded, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}">
                    <DataGridCheckBoxColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                        </Style>
                    </DataGridCheckBoxColumn.HeaderStyle>
                    <DataGridCheckBoxColumn.ElementStyle>
                        <Style>
                            <Setter Property="TextBlock.HorizontalAlignment" Value="Center" />
                            <Setter Property="TextBlock.VerticalAlignment" Value="Center" />
                        </Style>
                    </DataGridCheckBoxColumn.ElementStyle>
                    <DataGridCheckBoxColumn.CellStyle>
                        <Style>
                            <EventSetter Event="CheckBox.Checked" Handler="handleChecked" />
                            <EventSetter Event="CheckBox.Unchecked" Handler="handleChecked" />
                        </Style>
                    </DataGridCheckBoxColumn.CellStyle>
                </DataGridCheckBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
    <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="20,0,10,0">
        <Button Click="handleSendButton" Height="30" Width="70">Send</Button>
    </StackPanel>
</Grid>

代码背后:

namespace TheProgram
{

class NewsSrcTableItm
{
    public string heading { get; set; }
    public NewsItem itm { get; set; }
    public bool isIncluded { get; set; }
}

public partial class MainWindow : Window
{

    private List<NewsItem> includedList = null;

    public MainWindow()
    {
       InitializeComponent();
        setNewsSourceComboBox();

        this.includedList = new List<NewsItem>();

        initializeNewsTable();
    }

    private void setNewsSourceComboBox()
    {
        ComboBox cbx = (ComboBox)this.FindName("newsSrc");
        cbx.ItemsSource = MainWinClass.comboBoxList();
        cbx.SelectedIndex = 0;

        ComboBox cbx1 = (ComboBox)this.FindName("newsCategory");
        cbx1.ItemsSource = MainWinClass.categoryList();
        cbx1.SelectedIndex = 0;
    }

    private void initializeNewsTable()
    {
        newsStories.ItemsSource = MainWinClass.initializeNewsSource();
    }


    public void handleChecked(object sender, RoutedEventArgs e)
    {
        ComboBox cbx = this.FindName("newsCategory") as ComboBox;
        String theSelected = Regex.Replace(cbx.SelectedValue.ToString(), " ", String.Empty);
        String theNewsCategory = char.ToLower(theSelected[0]) + theSelected.Substring(1);
        foreach (var r in newsStories.ItemsSource)
        {
            NewsSrcTableItm itm = (NewsSrcTableItm)r;
            if (itm.isIncluded)
            {
                if (itm.itm.getCategory() == null)
                {
                    itm.itm.setCategory(theNewsCategory);
                }
                this.includedList.Add(itm.itm);
            }
        }
    }

    public void handleNewsSrcChange(object Sender, EventArgs args)
    {
        ComboBox cb = this.FindName("newsSrc") as ComboBox;
        newsStories.ItemsSource = MainWinClass.changeSource(cb.SelectedValue.ToString());
    }

    public async void handleSendButton(object Sender, EventArgs args)
    {
        NewsItem itm = this.includedList[0];
        String category = itm.getCategory();
        String title = itm.getHeading();
        String extract = null;
        String content = null;
        String timestamp = DateTime.Now.ToString("yyyyMMdd");
        NewsContentFetcher f = new NewsContentFetcher(itm.getUrl());
        List<String> theList = await f.getContent();
        extract = theList[0];
        foreach (String s in theList)
        {
            content += s;
        }
        HttpClient client = new HttpClient();
        var values = new Dictionary<String, String> 
        {
            { "category", category },
            { "title", title },
            { "extract", extract },
            { "content", content },
            { "timestamp", timestamp }
        };
        var theContent = new FormUrlEncodedContent(values);
        var result = client.PostAsync("http://localhost/addNews.php", theContent).Result;
        int statusCode = (int)result.StatusCode;
        if (statusCode == 200)
        {
            MessageBox.Show("Completed");
        }
        else
        {
            MessageBox.Show("failed");
        }
    }

}
}

1 个答案:

答案 0 :(得分:0)

  

但是,无论如何直接获取复选框索引以便我可以修改给定索引的绑定数据吗?

试试这个:

public void handleChecked(object sender, RoutedEventArgs e)
{
    CheckBox chk = e.OriginalSender as CheckBox;
    NewsSrcTableItm itm = chk.DataContext as NewsSrcTableItm;

    //get index:
    var sourceCollection = newsStories.ItemsSource as IList<NewsSrcTableItm>;
    int index = sourceCollection.IndexOf(itm);
    //...
}