亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用戶控件綁定未返回正確的值

用戶控件綁定未返回正確的值

C#
喵喵時光機 2023-07-09 16:34:29
我制作了一個由 3 個滑塊和一些標簽組成的 UserControl。用于操縱類的平移、旋轉和縮放值。每個用戶控件都有自己的平移、旋轉和縮放屬性。相應滑塊的值綁定到此屬性。這一切都會正常工作,直到用戶嘗試通過用鼠標滑動滑塊來手動更改該值。無論出于何種原因,這都不會更新該屬性。這是如何設置其中一個滑塊的示例:<Slider?x:Name="sliderTranslation"?Grid.Column="1"?Grid.Row="1"?VerticalAlignment="Center"?ToolTip="{Binding?Value,?RelativeSource={RelativeSource?Self}}"?Value="{Binding?Path=Translation}"?Thumb.DragCompleted="SliderTranslation_DragCompleted"?Maximum="65535"?TickFrequency="0"?SmallChange="1"?AutoToolTipPlacement="TopLeft"/>這就是我的 DataGrid 的設置方式:<DataGrid x:Name="dgValueList" Margin="10,72,10,76" SelectionMode="Single" IsReadOnly="True" BorderThickness="2" AlternationCount="2" EnableRowVirtualization="False">? ? <DataGrid.Columns>? ? ? ? <DataGridTemplateColumn Header="Face Values" Width="*" CanUserReorder="False">? ? ? ? ? ? <DataGridTemplateColumn.CellTemplate>? ? ? ? ? ? ? ? <DataTemplate>? ? ? ? ? ? ? ? ? ? <local:FaceValueSlider/>? ? ? ? ? ? ? ? </DataTemplate>? ? ? ? ? ? </DataGridTemplateColumn.CellTemplate>? ? ? ? </DataGridTemplateColumn>? ? </DataGrid.Columns></DataGrid>所以對于一些背景。DataGrid 由 49 個這樣的用戶控件組成。所以本質上總共有 147 個滑塊。讓我們以第一個 UserControl 為例,它有這些值;平移:3380旋轉:49972比例:16807如果我將翻譯滑塊移動到最大值(65535)并保存,我得到的返回值仍然是 3380。但是,如果我通過我添加的方法更新它們,它會按預期工作。只有當他們嘗試手動滑動它時,它才會這樣做。除此之外,我還收到 51 條與 UserControls 相關的警告,但我不知道它們的含義。這是其中 2 個:System.Windows.Data 警告:4:無法找到引用&ldquo;RelativeSource FindAncestor、AncestorType='System.Windows.Controls.ItemsControl&rdquo;、AncestorLevel='1'' 進行綁定的源。BindingExpression:Path=HorizontalContentAlignment;?數據項=空;目標元素是&ldquo;ListBoxItem&rdquo;(名稱=&ldquo;&rdquo;);目標屬性是&ldquo;HorizontalContentAlignment&rdquo;(類型&ldquo;HorizontalAlignment&rdquo;)System.Windows.Data 警告:4:無法找到引用&ldquo;RelativeSource FindAncestor、AncestorType='System.Windows.Controls.ItemsControl&rdquo;、AncestorLevel='1'' 進行綁定的源。綁定表達式:路徑=(0);?數據項=空;目標元素是&ldquo;ListBoxItem&rdquo;(名稱=&ldquo;&rdquo;);目標屬性是&ldquo;ClearTypeHint&rdquo;(類型&ldquo;ClearTypeHint&rdquo;),我這整個綁定的事情做錯了嗎?我嘗試在創建 UserControls 時將其添加到列表中,并設置 DataGrid 的 ItemsSource。
查看完整描述

1 回答

?
飲歌長嘯

TA貢獻1951條經驗 獲得超3個贊

這里有太多錯誤,向您展示正確的代碼比解釋所有內容更容易。閱讀我上面鏈接的文章并研究這段代碼。我還沒有完全按照我的方式重新設計:例如,沒有主視圖模型?,F在這不是 MVVM 的一個很好的示例,但它說明了您在網格中放置了哪些內容、如何編寫模板列以及如何正確更新屬性。

首先,您使用用戶控件的實例作為同一控件的視圖模型,但它并不是真正的視圖模型,因為它從不引發任何屬性更改通知。讓我們為網格編寫一個實際的項目視圖模型。這不是 UI 控件。它是數據,將顯示UI 控件中。它擁有信息,并且當信息發生變化時它會收到通知。如果你愿意的話,它也可以有一些邏輯。

public class SliderItem : ObservableObject

{

? ? public SliderItem()

? ? {

? ? }


? ? public SliderItem(int trans, int rot, int scale)

? ? {

? ? ? ? Translation = trans;

? ? ? ? Rotation = rot;

? ? ? ? Scale = scale;

? ? }


? ? public void UpdateValues(int newTrans, int newRot, int newScale)

? ? {

? ? ? ? Translation = newTrans;

? ? ? ? Rotation = newRot;

? ? ? ? Scale = newScale;

? ? }


? ? public void UpdateDescription(string newText)

? ? {

? ? ? ? if(!String.IsNullOrWhiteSpace(newText))

? ? ? ? {

? ? ? ? ? ? Description = newText;

? ? ? ? ? ? OnPropertyChanged(nameof(Description));

? ? ? ? }

? ? }


? ? public String Description { get; private set; }


? ? private int _translation = 0;

? ? public int Translation

? ? {

? ? ? ? get { return _translation; }

? ? ? ? set

? ? ? ? {

? ? ? ? ? ? if (value != _translation)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? _translation = value;

? ? ? ? ? ? ? ? OnPropertyChanged(nameof(Translation));

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? private int _rotation = 0;

? ? public int Rotation

? ? {

? ? ? ? get { return _rotation; }

? ? ? ? set

? ? ? ? {

? ? ? ? ? ? if (value != _rotation)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? _rotation = value;

? ? ? ? ? ? ? ? OnPropertyChanged(nameof(Rotation));

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? private int _scale = 0;

? ? public int Scale

? ? {

? ? ? ? get { return _scale; }

? ? ? ? set

? ? ? ? {

? ? ? ? ? ? if (value != _scale)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? _scale = value;

? ? ? ? ? ? ? ? OnPropertyChanged(nameof(Scale));

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

TripleSlider.xaml


TripleSlider 的 XAML 基本上沒問題;主要問題是它正在尋找以前不存在的視圖模型。但我們還希望滑塊值綁定在Value更改時更新綁定屬性,而不是在滑塊控件失去焦點時(這是不明顯的默認行為)。因此,添加UpdateSourceTrigger=PropertyChanged到所有三個 Slider.Value 綁定。


? ? Value="{Binding Path=Translation, UpdateSourceTrigger=PropertyChanged}"?

TripleSlider.xaml.cs


就是這個。這就是該類應該的樣子。


public partial class TripleSlider : UserControl

{

? ? public TripleSlider()

? ? {

? ? ? ? InitializeComponent();

? ? }

}

MainWindow.xaml 沒問題。MainWindow.xaml.cs 做了一些更改:


public partial class MainWindow : Window

{

? ? //? Don't use arrays. Use ObservableCollection<WhateverClass> for binding to UI controls,

? ? //? use List<Whatever> for anything else.?

? ? private ObservableCollection<SliderItem> _sliders = new ObservableCollection<SliderItem>();

? ? public MainWindow()

? ? {

? ? ? ? InitializeComponent();


? ? ? ? //? The ObservableCollection will notify the grid when you add or remove items

? ? ? ? //? from the collection. Set this and forget it. Everywhere else, interact with?

? ? ? ? //? _sliders, and let the DataGrid handle its end by itself.?

? ? ? ? //? Also get rid of EnableRowVirtualization="False" from the DataGrid. Let it?

? ? ? ? //? virtualize.?

? ? ? ? myDataGrid.ItemsSource = _sliders;

? ? }


? ? private void BAddControls_Click(object sender, RoutedEventArgs e)

? ? {

? ? ? ? for (int i = 0; i < 49; i++)

? ? ? ? {

? ? ? ? ? ? var newSlider = new SliderItem();

? ? ? ? ? ? newSlider.UpdateDescription(String.Format("{0}: Unkown Value", (i+1)));

? ? ? ? ? ? newSlider.UpdateValues((i+1)*1337, (i+1)*1337, (i+1)*1337);

? ? ? ? ? ? _sliders.Add(newSlider);

? ? ? ? }


? ? ? ? bAddControls.IsEnabled = false;

? ? }


? ? private void BFetchValues_Click(object sender, RoutedEventArgs e)

? ? {

? ? ? ? if (myDataGrid.SelectedItem != null)

? ? ? ? {

? ? ? ? ? ? var selectedSlider = myDataGrid.SelectedItem as SliderItem;

? ? ? ? ? ? MessageBox.Show(String.Format("Translation: {0}\nRotation: {1}\nScale: {2}", selectedSlider.Translation, selectedSlider.Rotation, selectedSlider.Scale), "Information", MessageBoxButton.OK, MessageBoxImage.Information);

? ? ? ? }

? ? }


? ? private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)

? ? {

? ? ? ? bFetchValues.IsEnabled = (myDataGrid.SelectedItem != null) ? true : false;

? ? }

}


查看完整回答
反對 回復 2023-07-09
  • 1 回答
  • 0 關注
  • 117 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號