【问题标题】:How can I use the Two-Way Binding in a ListBox?如何在 ListBox 中使用双向绑定?
【发布时间】:2018-01-07 05:00:42
【问题描述】:

我有一个 ListBox,其中包括一个带有 StackPanel 的 ItemTemplate。我为我的 Listbox itemsource 分配了一个通用列表。我想更改该 stackpanel 的可见性。 (当我单击mouseleftbutton“closeAll”并关闭Listbox中的所有stackPanel项目时,将其可见性更改为折叠)。我想使用stackpanel可见性= {Binding Acikmi}来做到这一点。 我有 PastAndOr 类和它的属性“Acikmi”,它的第一个值是“可见的”。 如何使用绑定双向模式将“Acikmi”值从“可见”更改为“折叠”?

public static List<PastAndOr> GetPastOr()
{
    string connStr = "server=localhost;user=root;database=carbovisor;port=3306;password=12345";
    MySqlConnection conn = new MySqlConnection(connStr);
    conn.Open();
    MySqlCommand cmd = new MySqlCommand("SELECT s.sarjno as sarjno,s.createdate as createdate,m.adi as madi,mp.parcakodu as parcakodu,mp.parcaadi as parcaadi,mp.malzeme as malzeme,mr.kodu as musterikodu,mr.adi as musteriadi FROM  t_sepetler s JOIN  t_mamul m ON m.adi=@receteadi OR m.id=s.mamulid LEFT JOIN t_musteriparca mp ON mp.firmaid=s.musteriid LEFT JOIN t_musteriler mr ON mr.id=mp.firmaid  WHERE s.createdate >= @tarih1 AND s.createdate <= @tarih2  GROUP BY sarjno,madi  ORDER BY createdate DESC", conn);
    cmd.Parameters.AddWithValue("@tarih1", PastProcess.tarih1);
    cmd.Parameters.AddWithValue("@tarih2", PastProcess.tarih2);
    cmd.Parameters.AddWithValue("@receteadi", PastProcess.receteadi);
    cmd.Parameters.AddWithValue("@sarjno", PastProcess.sarjno);

    MySqlDataReader dataReader = cmd.ExecuteReader();
    List<PastAndOr> or = new List<PastAndOr>();
    PastAndOr kayit2;
    int IDSayac = 1;
    while (dataReader.Read())
    {
        kayit2 = new PastAndOr();

        kayit2.Adi = dataReader["madi"].ToString();
        kayit2.SarjNo = dataReader["sarjno"].ToString();
        kayit2.CreateDate = dataReader["createdate"].ToString();
        kayit2.ParcaKodu = dataReader["parcakodu"].ToString();
        kayit2.ParcaKoduAdi = dataReader["parcakodu"].ToString() + " - " + dataReader["parcaadi"].ToString();
        kayit2.Malzeme = dataReader["malzeme"].ToString();
        kayit2.MusteriKodu = dataReader["musterikodu"].ToString();
        kayit2.MusteriKoduAdi = dataReader["musterikodu"].ToString() + " - " + dataReader["musteriadi"].ToString();

        kayit2.Acikmi = Visibility.Visible;

        kayit2.ID = IDSayac;

        or.Add(kayit2);
        IDSayac++;
    }

    conn.Close();

    return or;
}

private void closeAll_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // what goes here?
}


public class PastAndOr
{
    public Visibility Acikmi { get; set; }
    public int ID { get; set; }
    public string Adi { get; set; }
    public string SarjNo { get; set; }
    public string CreateDate { get; set; }
    public string ParcaKodu { get; set; }
    public string ParcaKoduAdi { get; set; }
    public string Malzeme { get; set; }
    public string MusteriKodu { get; set; }
    public string MusteriKoduAdi { get; set; }
}

XAML 代码

<ListBox x:Name="listBoxEditPast"  SelectionMode="Single"  Margin="0" Background="#272B34" ScrollViewer.VerticalScrollBarVisibility="Visible">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Border Grid.Row="0"   BorderThickness="4,0,0,0" Margin="2,0,0,0" Height="29"  Background="#2E323B" Width="1050" BorderBrush="#1373A9" MouseLeftButtonDown="Border_MouseLeftButtonDown">
                                    <DockPanel Name="dockPanelPast" Margin="0,4,0,0">
                                        <Image Name="imgArrow" Source="images/down-arrow.png" HorizontalAlignment="Left" Width="20" Height="18"/>
                                        <TextBlock Text="{Binding CreateDate}" Name="txtTarih" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16"/>
                                        <TextBlock Text="{Binding SarjNo}" Name="txtSarjNo" Foreground="#FF9CA518" HorizontalAlignment="Stretch" VerticalAlignment="Center" FontSize="16" Margin="50,0,0,0" Width="90"/>
                                        <TextBlock Text="{Binding Adi}" Name="txtReceteAdi" Foreground="#FF26A053"  VerticalAlignment="Center" FontSize="16" Margin="40,0,0,0" HorizontalAlignment="Stretch"/>
                                        <Button Content="Detaylar" Style="{StaticResource BlueButton}" HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" DockPanel.Dock="Right"/>
                                    </DockPanel>
                                </Border>
                                <StackPanel Grid.Row="1"  Name="stackPanelDetay" Tag="{Binding ID}" Visibility="{Binding Acikmi,Mode=TwoWay}">
                                    <DockPanel>
                                        <TextBlock Text="Sipariş No" Foreground="#D9480F" VerticalAlignment="Center" />
                                        <TextBlock Text="Parça" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="50,0,0,0" Width="200" />
                                        <TextBlock Text="Malzeme" Foreground="White" VerticalAlignment="Center" Margin="150,0,0,0" Width="90"/>
                                        <TextBlock Text="Müşteri" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="70,0,0,0" />
                                    </DockPanel>
                                    <DockPanel>
                                        <TextBlock Text="{Binding ID}" Foreground="White"  VerticalAlignment="Center" Width="100"/>
                                        <TextBlock Text="{Binding ParcaKoduAdi}" Foreground="White"  VerticalAlignment="Center" Margin="5,0,0,0" Width="200"  />
                                        <TextBlock Text="{Binding Malzeme}" Foreground="White"  VerticalAlignment="Center" Margin="152,0,0,0" Width="90" />
                                        <TextBlock Text="{Binding MusteriKoduAdi}" Foreground="White"  VerticalAlignment="Center" Margin="70,0,0,0" />
                                    </DockPanel>
                                </StackPanel>
                            </Grid>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

【问题讨论】:

  • 欢迎来到 StackOverflow!请确保您首先阅读了How to Ask 帮助页面。我们希望看到minimal reproducible example(密切注意那个minimal 字)。我还修改了您问题的标题,因为它不应包含强制标签。
  • 绑定不应该是双向的。相反,您的按钮操作应该直接设置所有应该不可见的PastAndOr 项目的Acikmi 属性。因此,该类应实现 INotifyPropertyChanged 接口并在属性值更改时触发 PropertyChanged 事件。
  • INotifyPropertyChanged 缺失。

标签: c# wpf xaml binding listbox


【解决方案1】:

你的类应该实现 INoyifyPropertyChanged 接口。阅读有关 WPF INoyifyPropertyChanged 的​​更多详细信息。

 public class PastAndOr:INotifyPropertyChanged
{
    public Visibility _acikmi;
    public Visibility Acikmi
    {
        get {return _acikmi; }
        set
        {
            _acikmi = value;
            OnPropertyChaged(nameof(Acikmi));
        }
    }
    public int ID { get; set; }
    public string Adi { get; set; }
    public string SarjNo { get; set; }
    public string CreateDate { get; set; }
    public string ParcaKodu { get; set; }
    public string ParcaKoduAdi { get; set; }
    public string Malzeme { get; set; }
    public string MusteriKodu { get; set; }
    public string MusteriKoduAdi { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChaged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML 就像

<StackPanel Grid.Row="1"  Name="stackPanelDetay" Tag="{Binding ID}" Visibility="{Binding Acikmi}">

【讨论】:

  • 删除了 Mode=TwoWayUpdateSourceTrigger=PropertyChanged。两者都没有任何意义。除此之外,“你的班级应该是这样的”并没有解释任何事情。您可能想在答案中添加一些解释性细节。
  • 感谢 Ramankingdom 和 Clemens 的回答。但是如何在“closeAll_MouseLeftButtonDown”方法中设置 Acikmi 属性,我该怎么做?我想将“Acikmi”属性设置为 visibility.collapsed .
【解决方案2】:

要在 MVVM 中最好地做到这一点,您将使用 ICommand。 可以在 here 找到一个很好的 ICommand 实现示例

基本上 ICommands 可以绑定到 ButtonBase.Command 属性,但是在您的情况下,您希望将其链接到 MouseLeftButtonDown 事件。交互触发器正是为此目的而存在的。

通过 NuGet 将 Expressions Blend SDK 添加到您的项目中。 将交互性 xmlns 添加到您的命名空间:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

最后使用触发器和操作链接到您的 ICommand 属性,如下所示:

<Border>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseLeftButtonDown">
                <i:InvokeCommandAction Command="{Binding Path=MyCommand}"></i:InvokeCommandAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Border>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 2022-07-20
    • 2017-04-01
    • 1970-01-01
    • 2016-03-16
    • 2015-03-13
    • 2011-01-27
    • 2021-06-10
    相关资源
    最近更新 更多