View Full Version : سوال: اعمال تغییرات در نودهای فرزند موقع تغییر در نود پدر در treeview
elahe1393
یک شنبه 20 تیر 1400, 09:15 صبح
سلام وقت بخیر
یه treeview دارم که هر شاخه آن دارای یک textbox یه Combobox و یک checkbox هست و همین طور یک فرم پاپ آپ که یه سری فیلد دیگه ای داخل این popUp هست میخوام وقتی یه textbox در شاخه پدر تغییر میکنه combobox شاخه های فرزند هم تغییر کنه و وقتی مقدار عددی یه textbox شاخه پدر تغییر میکنه به زیر شاخه ها هم اعمال بشه الان من برای هر شاخه به طور مجزا برای هر فیلد یه textchange یا click یا event های موردنظر رو کدنویسی کردم الان خیلی کدم بزرگ شده و تغییر جزی نیاز به تغییر کل زیرشاخه های این درخت داره میخوام یه روشی استفاده کنم که نیاز باشه فقط چند تابع اصلی بنویسم که برای همه زیرشاخه ها اعمال بشه البته با انتخاب مثلا یه شاخه پدر تغییر برروی زیر شاخه های فرزند اعمال بشه امکانش هست منو راهنمایی کنید ممنون میشم
مثلا هر شاخه مشابه کد زیر فیلدهای مختلف داره و همه شاخه ها این فیلدهارو داره که باید به طور مجزا مقداردهی بشن ولی اگر شاخه پدر تغییر کنه باید یه جوری مقادیرشون مثلا برای تکست باکس تقسیم بشه بین زیرشاخه ها یا مثلا کمبوباکس باید مقدارش یکی باشه
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Name="SpeedCbx" Text="سرعتی "></TextBlock>
<TextBox Name="Speedtxt" Height="20" Width="35" TextChanged="Speedtxt_TextChanged" ></TextBox>
<ComboBox Foreground="{Binding BackgroundTextControl}" FontSize="15" Style="{DynamicResource ComboBoxStyle}" Height="20" Width="50" x:Name="cbxSpeed" SelectionChanged="cbxSpeed_SelectionChanged" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Margin="2,0"/>
<CheckBox x:Name="cbSpeed" FontSize="15" VerticalAlignment="Center" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Click="cbSpeed_Click" Margin="2,0"/>
<Button Style="{DynamicResource ButtonCustomize}" x:Name="btnCustomizeSpeed" Content="سفارشی" FontSize="15" Click="btnCustomizeSpeed_Click" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Margin="2,0"></Button>
<Popup Name="popupCustomizeSpeed" HorizontalAlignment="Stretch" AllowsTransparency="True" VerticalAlignment="Stretch" Placement="Center">
<Border Background="{Binding Background}" CornerRadius="10" Padding="30" Margin="30,10,50,10">
<Grid FlowDirection="RightToLeft">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Name="TimePercentSpeedlbl" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">درصد زمان</TextBlock>
<ComboBox Style="{DynamicResource ComboBoxStyle}" Grid.Row="0" Grid.Column="1" Name="TimePercentSpeedcbx" Width="50" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">
<ComboBoxItem>01</ComboBoxItem>
<ComboBoxItem>02</ComboBoxItem>
<ComboBoxItem>03</ComboBoxItem>
<ComboBoxItem>04</ComboBoxItem>
<ComboBoxItem>05</ComboBoxItem>
<ComboBoxItem>06</ComboBoxItem>
<ComboBoxItem>07</ComboBoxItem>
<ComboBoxItem>08</ComboBoxItem>
<ComboBoxItem>09</ComboBoxItem>
<ComboBoxItem>10</ComboBoxItem>
<ComboBoxItem>11</ComboBoxItem>
<ComboBoxItem>12</ComboBoxItem>
<ComboBoxItem>13</ComboBoxItem>
<ComboBoxItem>14</ComboBoxItem>
<ComboBoxItem>15</ComboBoxItem>
<ComboBoxItem>16</ComboBoxItem>
<ComboBoxItem>17</ComboBoxItem>
<ComboBoxItem>18</ComboBoxItem>
<ComboBoxItem>19</ComboBoxItem>
<ComboBoxItem>20</ComboBoxItem>
<ComboBoxItem>21</ComboBoxItem>
</ComboBox>
<TextBlock Grid.Row="1" Grid.Column="0" Name="ExtensionSpeedlbl" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">اندازه توپ</TextBlock>
<ComboBox Style="{DynamicResource ComboBoxStyle}" Grid.Row="1" Grid.Column="1" Name="ExtensionSpeedcbx" Width="50" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">
<ComboBoxItem>01</ComboBoxItem>
<ComboBoxItem>02</ComboBoxItem>
<ComboBoxItem>03</ComboBoxItem>
<ComboBoxItem>04</ComboBoxItem>
<ComboBoxItem>05</ComboBoxItem>
<ComboBoxItem>06</ComboBoxItem>
<ComboBoxItem>07</ComboBoxItem>
<ComboBoxItem>08</ComboBoxItem>
<ComboBoxItem>09</ComboBoxItem>
<ComboBoxItem>10</ComboBoxItem>
<ComboBoxItem>11</ComboBoxItem>
<ComboBoxItem>12</ComboBoxItem>
<ComboBoxItem>13</ComboBoxItem>
<ComboBoxItem>14</ComboBoxItem>
<ComboBoxItem>15</ComboBoxItem>
<ComboBoxItem>16</ComboBoxItem>
<ComboBoxItem>17</ComboBoxItem>
<ComboBoxItem>18</ComboBoxItem>
<ComboBoxItem>19</ComboBoxItem>
<ComboBoxItem>20</ComboBoxItem>
<ComboBoxItem>21</ComboBoxItem>
</ComboBox>
<Button x:Name="btnCreateCustomizeSpeed" Grid.Column="1" Style="{DynamicResource ButtonCreate}"
HorizontalAlignment="Left" Margin="40,0,0,10" VerticalAlignment="Bottom" Background="White"
Foreground="Black" FontSize="21.333" FontWeight="Bold" Grid.Row="3" Click="btnCreateCustomizeSpeed_Click" FontFamily="/Rehab.GUI;component/Font/#B Nazanin"/>
<Button Style="{DynamicResource ButtonExit}" Grid.Row="0" Grid.Column="0" Margin="-30,-30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White"
Foreground="Black" FontSize="21.333" FontWeight="Bold" Click="BtnSpeedExit" FontFamily="/Rehab.GUI;component/Font/#B Nazanin"/>
</Grid>
</Border>
</Popup>
</StackPanel>
</TreeViewItem.Header>
SajjadKhati
پنج شنبه 24 تیر 1400, 12:19 عصر
سلام
چرا نودهای فرزند را به پدر ، binding نمیکنید؟
barnamenevisjavan
پنج شنبه 24 تیر 1400, 22:23 عصر
سلام وقت بخیر
یه treeview دارم که هر شاخه آن دارای یک textbox یه Combobox و یک checkbox هست و همین طور یک فرم پاپ آپ که یه سری فیلد دیگه ای داخل این popUp هست میخوام وقتی یه textbox در شاخه پدر تغییر میکنه combobox شاخه های فرزند هم تغییر کنه و وقتی مقدار عددی یه textbox شاخه پدر تغییر میکنه به زیر شاخه ها هم اعمال بشه الان من برای هر شاخه به طور مجزا برای هر فیلد یه textchange یا click یا event های موردنظر رو کدنویسی کردم الان خیلی کدم بزرگ شده و تغییر جزی نیاز به تغییر کل زیرشاخه های این درخت داره میخوام یه روشی استفاده کنم که نیاز باشه فقط چند تابع اصلی بنویسم که برای همه زیرشاخه ها اعمال بشه البته با انتخاب مثلا یه شاخه پدر تغییر برروی زیر شاخه های فرزند اعمال بشه امکانش هست منو راهنمایی کنید ممنون میشم
مثلا هر شاخه مشابه کد زیر فیلدهای مختلف داره و همه شاخه ها این فیلدهارو داره که باید به طور مجزا مقداردهی بشن ولی اگر شاخه پدر تغییر کنه باید یه جوری مقادیرشون مثلا برای تکست باکس تقسیم بشه بین زیرشاخه ها یا مثلا کمبوباکس باید مقدارش یکی باشه
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Name="SpeedCbx" Text="سرعتی "></TextBlock>
<TextBox Name="Speedtxt" Height="20" Width="35" TextChanged="Speedtxt_TextChanged" ></TextBox>
<ComboBox Foreground="{Binding BackgroundTextControl}" FontSize="15" Style="{DynamicResource ComboBoxStyle}" Height="20" Width="50" x:Name="cbxSpeed" SelectionChanged="cbxSpeed_SelectionChanged" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Margin="2,0"/>
<CheckBox x:Name="cbSpeed" FontSize="15" VerticalAlignment="Center" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Click="cbSpeed_Click" Margin="2,0"/>
<Button Style="{DynamicResource ButtonCustomize}" x:Name="btnCustomizeSpeed" Content="سفارشی" FontSize="15" Click="btnCustomizeSpeed_Click" FontFamily="/Rehab.GUI;component/Font/#B Nazanin" Margin="2,0"></Button>
<Popup Name="popupCustomizeSpeed" HorizontalAlignment="Stretch" AllowsTransparency="True" VerticalAlignment="Stretch" Placement="Center">
<Border Background="{Binding Background}" CornerRadius="10" Padding="30" Margin="30,10,50,10">
<Grid FlowDirection="RightToLeft">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Name="TimePercentSpeedlbl" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">درصد زمان</TextBlock>
<ComboBox Style="{DynamicResource ComboBoxStyle}" Grid.Row="0" Grid.Column="1" Name="TimePercentSpeedcbx" Width="50" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">
<ComboBoxItem>01</ComboBoxItem>
<ComboBoxItem>02</ComboBoxItem>
<ComboBoxItem>03</ComboBoxItem>
<ComboBoxItem>04</ComboBoxItem>
<ComboBoxItem>05</ComboBoxItem>
<ComboBoxItem>06</ComboBoxItem>
<ComboBoxItem>07</ComboBoxItem>
<ComboBoxItem>08</ComboBoxItem>
<ComboBoxItem>09</ComboBoxItem>
<ComboBoxItem>10</ComboBoxItem>
<ComboBoxItem>11</ComboBoxItem>
<ComboBoxItem>12</ComboBoxItem>
<ComboBoxItem>13</ComboBoxItem>
<ComboBoxItem>14</ComboBoxItem>
<ComboBoxItem>15</ComboBoxItem>
<ComboBoxItem>16</ComboBoxItem>
<ComboBoxItem>17</ComboBoxItem>
<ComboBoxItem>18</ComboBoxItem>
<ComboBoxItem>19</ComboBoxItem>
<ComboBoxItem>20</ComboBoxItem>
<ComboBoxItem>21</ComboBoxItem>
</ComboBox>
<TextBlock Grid.Row="1" Grid.Column="0" Name="ExtensionSpeedlbl" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">اندازه توپ</TextBlock>
<ComboBox Style="{DynamicResource ComboBoxStyle}" Grid.Row="1" Grid.Column="1" Name="ExtensionSpeedcbx" Width="50" FontFamily="/Rehab.GUI;component/Font/#B Nazanin">
<ComboBoxItem>01</ComboBoxItem>
<ComboBoxItem>02</ComboBoxItem>
<ComboBoxItem>03</ComboBoxItem>
<ComboBoxItem>04</ComboBoxItem>
<ComboBoxItem>05</ComboBoxItem>
<ComboBoxItem>06</ComboBoxItem>
<ComboBoxItem>07</ComboBoxItem>
<ComboBoxItem>08</ComboBoxItem>
<ComboBoxItem>09</ComboBoxItem>
<ComboBoxItem>10</ComboBoxItem>
<ComboBoxItem>11</ComboBoxItem>
<ComboBoxItem>12</ComboBoxItem>
<ComboBoxItem>13</ComboBoxItem>
<ComboBoxItem>14</ComboBoxItem>
<ComboBoxItem>15</ComboBoxItem>
<ComboBoxItem>16</ComboBoxItem>
<ComboBoxItem>17</ComboBoxItem>
<ComboBoxItem>18</ComboBoxItem>
<ComboBoxItem>19</ComboBoxItem>
<ComboBoxItem>20</ComboBoxItem>
<ComboBoxItem>21</ComboBoxItem>
</ComboBox>
<Button x:Name="btnCreateCustomizeSpeed" Grid.Column="1" Style="{DynamicResource ButtonCreate}"
HorizontalAlignment="Left" Margin="40,0,0,10" VerticalAlignment="Bottom" Background="White"
Foreground="Black" FontSize="21.333" FontWeight="Bold" Grid.Row="3" Click="btnCreateCustomizeSpeed_Click" FontFamily="/Rehab.GUI;component/Font/#B Nazanin"/>
<Button Style="{DynamicResource ButtonExit}" Grid.Row="0" Grid.Column="0" Margin="-30,-30,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White"
Foreground="Black" FontSize="21.333" FontWeight="Bold" Click="BtnSpeedExit" FontFamily="/Rehab.GUI;component/Font/#B Nazanin"/>
</Grid>
</Border>
</Popup>
</StackPanel>
</TreeViewItem.Header>
کدی که قرار دادید چیزی مشخص نیست، نحوه فراخوانی و اتصال داده ها مشخص نیست، طبق گفته دوستمون باید اطلاعات رو bind کنید
و اینکه کد شما پر از ایراد هست به جای DynamicResource از StaticResource استفاده کنید، فونت رو میتونید یکبار به window اعمال کنید تا به تمام المنت ها بصورت خودکار اعمال بشه
elahe1393
شنبه 26 تیر 1400, 18:23 عصر
چطور بایند کنم؟
elahe1393
شنبه 26 تیر 1400, 18:36 عصر
این درخت من از یه سری یوزر کنترل تشکیل شده این کدی که نشان دادم یه بخشهایی از یکی از یوزرکنترل ها هست میخوام نیاز نباشه برای هر شاخه و زیرشاخه یه تابع جدا برای عملیاتیکه باید انجام بشه بنویسم یجوری کدنویسی کنم که چندتا تابع اصلی باشه که با توجه به انتخاب مثلا یه دراپ داون از یه زیر شاخه متغیرهای موردنظر مقدار دهی بشه و تغییرات لازم مربوط به اون زیر شاخه انجام بشه ممنون میشم راهنمایی کنید
SajjadKhati
پنج شنبه 31 تیر 1400, 14:46 عصر
سلامبه کامپیوتر نمیتونم دسترسی داشته باشم . بنابراین در حد تئوری ، چیزهایی که میگم را اجرا کنید یا روش های دیگه که مد نظر خودتون میرسه ، ببینید جواب میده یا نه .
در تمپلیت ای که برای کنترل TreeViewItem ساختین :
https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/treeview-styles-and-templates?view=netframeworkdesktop-4.8
در تریگر ، با پروپرتیِ HasHeader ، یا پروپرتی های دیگه ای ، بررسی کنید ببینید اگه این کنترلِ TreeViewItem ، والدی داره ، در Setter ، پروپرتی های TargetName و Poperty را به عنوان binding target object و binding target property را تنظیم کنید و در پروپرتیِ Value ، بایندینگ انجام بدین و در RelativeSource اش، روی FindAncestor بذارید و AncestorType اش را روی نوعِ TreeViewItem بذارید تا والدش را چک کنه .
elahe1393
سه شنبه 16 شهریور 1400, 15:14 عصر
سلام ممنون از پاسخگوییهاتون
من یه مشکل توی کنترل treeview دارم
میخوام هر شاخه از درخت شامل یک textblock و یه textbox و یک checkbox و یه dropdown و یه button داشته باشه که از طریق کد شاخه هارو اضافه کنم وبا توجه به هر شاخه ای که هست مثلا اگر مقدار عددی textbox تغییر کرد تقسیم بر تعداد زیرشاخه باشه و زیرشاخه ها مقدار بگیره یا اینکه مثلا هر button با توجه به عنوان شاخه تابع خاصی رو انجام بده آیا میشه یه همچین کاری کرد؟ من در حال حاضر کل درخت رو ساختم و خیلی بزرگه میخوام خیلی ساده ترش کنم که با یه سری تابع اصلی بتونم مقادیر textbox یا dropdown و checkbox هاش رو مدیریت کنم
barnamenevisjavan
سه شنبه 16 شهریور 1400, 21:32 عصر
سلام ممنون از پاسخگوییهاتون
من یه مشکل توی کنترل treeview دارم
میخوام هر شاخه از درخت شامل یک textblock و یه textbox و یک checkbox و یه dropdown و یه button داشته باشه که از طریق کد شاخه هارو اضافه کنم وبا توجه به هر شاخه ای که هست مثلا اگر مقدار عددی textbox تغییر کرد تقسیم بر تعداد زیرشاخه باشه و زیرشاخه ها مقدار بگیره یا اینکه مثلا هر button با توجه به عنوان شاخه تابع خاصی رو انجام بده آیا میشه یه همچین کاری کرد؟ من در حال حاضر کل درخت رو ساختم و خیلی بزرگه میخوام خیلی ساده ترش کنم که با یه سری تابع اصلی بتونم مقادیر textbox یا dropdown و checkbox هاش رو مدیریت کنم
از itemTemplate استفاده کنید و textblock و... رو قرار بدید برای راحتی در انجام event ها چون از طریق itemtemplate به اسامی کنترل ها دسترسی ندارید، برای همین کنترل هایی که گفتید رو داخل UserControl چینش کنید و یوزرکنترل رو به عنوان itemtemplate قرار بدید اینجوری راحت میتونید کدهای مربوط به event هارو داخل یوزرکنترل بنویسید و به سایر کنترل ها دسترسی داشته باشید.
elahe1393
سه شنبه 16 شهریور 1400, 22:44 عصر
از itemTemplate استفاده کنید و textblock و... رو قرار بدید برای راحتی در انجام event ها چون از طریق itemtemplate به اسامی کنترل ها دسترسی ندارید، برای همین کنترل هایی که گفتید رو داخل UserControl چینش کنید و یوزرکنترل رو به عنوان itemtemplate قرار بدید اینجوری راحت میتونید کدهای مربوط به event هارو داخل یوزرکنترل بنویسید و به سایر کنترل ها دسترسی داشته باشید.
منظورتون اینه که یه یوزر کنترل بسازم و تمام کنترلهایی که گفتم رو درون این یوزر کنترل بسازم بعد توی درخت این یوزرکنترل رو اضافه کنم برای هر شاخه؟ من با itemtemplate زیاد آشنایی ندارم
فقط یه نکته ای من توی event ها نیاز دارم بدونم چندتا زیرشاخه وجود داره که یه سری محاسبات انجام بدم و بعد نتیجه شو توی textbox زیرشاخه ها مقداردهی کنم چطور میتونم توی یوزرکنترل این محاسبات رو انجام بدم یعنی تعداد زیرشاخه هارو بدست بیارم
ممنون میشم راهنمایی کنید شاید بخاطر ناآشنا بودن نتونسته باشم منظورمو برسونم
barnamenevisjavan
چهارشنبه 17 شهریور 1400, 11:20 صبح
منظورتون اینه که یه یوزر کنترل بسازم و تمام کنترلهایی که گفتم رو درون این یوزر کنترل بسازم بعد توی درخت این یوزرکنترل رو اضافه کنم برای هر شاخه؟ من با itemtemplate زیاد آشنایی ندارم
فقط یه نکته ای من توی event ها نیاز دارم بدونم چندتا زیرشاخه وجود داره که یه سری محاسبات انجام بدم و بعد نتیجه شو توی textbox زیرشاخه ها مقداردهی کنم چطور میتونم توی یوزرکنترل این محاسبات رو انجام بدم یعنی تعداد زیرشاخه هارو بدست بیارم
ممنون میشم راهنمایی کنید شاید بخاطر ناآشنا بودن نتونسته باشم منظورمو برسونم
یه یوزرکنترل میسازید و کنترل هارو قرار میدید همون textblock و button
بعد به این صورت به عنوان ایتم تمپلت معرفی میکنید
<TreeView>
<TreeView.ItemTemplate>
<local:UserControl/>
</TreeView.ItemTemplate>
</TreeView>
برای محاسبات هم حالا من دقیق نمیدونم میخاید چیکار کنید ولی شدنیه فقط یکم بین ویو ها باید پاسکاری کنید چون داخل یوزرکنترل به خود treeview دسترسی ندارید برای همین توی ایونت باید از طریق یه پراپرتی استاتیک به ویویی که treeview قرار داره وصل بشید و اونجا اطلاعات موردنظر رو دریافت کنید
برای مثال treeview داخل یه page یا window به اسم myWindow هستش
شما داخل کدهای این صفحه پراپرتی زیر رو تعریف میکنید
public static myWindow Instance;
بعد در متد سازنده مقدار دهیش میکنید
public myWindow()
{
InitializeComponent();
Instance = this;
}
حالا توی همون یوزرکنترل که شما ایونت رو نوشتید میتونید به همون myWindow وصل بشید و به treeview دسترسی داشته باشید
نحوه استفاده به این صورت هستش
myWindow.Instance.mytreeview
نکته ای که باید دقت کنید هر متدی که public باشه شما میتونی بهش دسترسی داشته باشی پس اگر با خطایی مواجه شدید که گفت به treeview دسترسی ندارید کافیه کد موردنظر رو داخل یه تابع پابلیک بنویسید. حالا که به treeview دسترسی دارید دیگه میتونید محاسبات رو انجام بدید
SajjadKhati
چهارشنبه 17 شهریور 1400, 17:40 عصر
سلام
در تکمیل عرایض جناب barnamenevisjavan اینکه ، برای دسترسی به TreeView ، نیاز به ساختن UserControl نیست :
اگه درون کد xaml ، از درون کدهایی که در پروپرتیِ TreeView.ItemTemplate مینویسین ، بخواین به پروپرتی ای از اعضای TreeView دسترسی داشته باشین ، Binding انجام میدین (مقدار AncestorType ئه RelativeSource را روی والدی که میخواین پیدا کنین ، تنظیم کنین که در اینجا همون TreeView هست) .
اگه درون کد سی شارپ میخواین از طریق شیِ DependencyObject (در اینجا همون TreeViewItem) ، به شیِ والدش (در اینجا TreeView) دسترسی پیدا کنین ، از متد استاتیکِ ItemsControl.ItemsControlFromItemContainer استفاده کنید .
اگه بر اساس نام ای که قبلا برای کنترل TreeView تعیین کردین ، میخواین در سی شارپ بهش دسترسی پیدا کنین که هیچ چی .
elahe1393
چهارشنبه 17 شهریور 1400, 22:07 عصر
ممنون از لطف بی دریغ هر دوی شما ایشالا که بتونم انجامش بدم
elahe1393
چهارشنبه 24 آذر 1400, 16:11 عصر
سلام وقت بخیر
ببخشید مزاحم وقتتون شدن نیاز به راهنمایی داشتم ممنون میشم کمکم کنید
من یه لیست درختی در برنامه دارم که از یه فایل متنی شاخه هاشو میسازه و هر شاخه چندین فرزند داره از طریق HierarchicalDataTemplate من شاخه های این درخت رو ساختم کد زیر نشان دهنده کد درخت هست
<TreeView Grid.Row="0" Name="TasksTree" ItemsSource="{Binding}" Margin="10" Background="{Binding BackgroundRowListControl}" BorderBrush="Transparent">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsChecked}"/>
<EventSetter Event="Selected" Handler="tvi_Selected"/>
<EventSetter Event="Unselected" Handler="tvi_UnSelected"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type Model:Group}" ItemsSource="{Binding SubGroups}">
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ButtonAddItem}" Click="btnAdd_Click" Visibility="{Binding AddVisibility}"/>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<!--<TreeView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ButtonAddItem}" Click="btnAdd_Click" Visibility="{Binding AddVisibility}"/>
<CheckBox Content="{Binding Name}" IsChecked="False" Click="ItemCbx_Click"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>-->
</TreeView>
یه مشکلی که برام پیش آمده اینکه میخوام وقتی یه شاخه انتخاب میشه تمام زیر شاخه هاش و شاخه پدر تیک بخوره و اگر تیک برداشته شد تمام زیر شاخه ها برداشته شود و اگر شاخه های هم ردیف این شاخه تیک نداشت شاخه پدر هم تیک برداشته شود و در لحظه کنترل treeview رفرش شود الان نمی دونم اینو چطور پیاده سازی کنم
SajjadKhati
چهارشنبه 24 آذر 1400, 20:26 عصر
سلام
جواب این پست را ببینید :
https://social.msdn.microsoft.com/Forums/vstudio/en-US/9fd804d5-050c-4b94-b877-a23d81782fce/automatically-check-treeview-child-nodes-when-parent-is-checked?forum=wpf
یک کلاس با نام Node طراحی کرد که اطلاعات فرزندان را در خودش ذخیره میکنه .
زمانی که پروپرتیِ IsChecked اش تغییر داده بشه ، همین پروپرتی از فرزندانش را هم به همین مقدار ، تغییر میده .
بعد ، در HierarchicalDataTemplate ، از این کلاس استفاده میکنه و به پروپرتیِ IsChecked ، بایندینگ انجام میده .
elahe1393
شنبه 27 آذر 1400, 15:08 عصر
سلام وقت بخیر
برای style دادن به combobox و button که در HierarchicalDataTemplate قرار داره چیکار باید کرد مگه فرق داره با بقیه موقعیتها این میپرسم چون وقتی بصورت دستی درخت رو میساختم بدون مشکل استایل اعمال میشد ولی الان همون استایل وقتی کنترلها داخل یک HierarchicalDataTemplate قرار گرفت اعمال نمیشه
نمونه کد بخش درختی
<TreeView ItemsSource="{Binding}" Grid.Row="1" Name="TaskTreeView" Margin="10,10,4,10" Background="{Binding BackgroundRowListControl}" BorderBrush="Transparent" MouseLeftButtonUp="TaskTreeView_MouseLeftButtonUp" >
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=OneWay}"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type Model:SelectedGroup}" ItemsSource="{Binding SubGroups}">
<StackPanel Orientation="Horizontal">
<Image Visibility="{Binding DeleteVisibility}" Width="13" Height="13" PreviewMouseLeftButtonDown="Image_PreviewMouseLeftButtonDown" Source="DeleteBlack.png" Margin="2,0"/>
<TextBlock Text="{Binding Name}" Margin="2,0"/>
<Image Visibility="{Binding ErrorVisibility}" Width="13" Height="13" PreviewMouseLeftButtonDown="Image_PreviewMouseLeftButtonDown" Source="Warning.png" ToolTip="{Binding ErrorText}" Margin="2,0"/>
<TextBox Text="{Binding YamlNumber}" ToolTip="تعداد تمرینات" IsEnabled="{Binding YamlNumIsEnable}" Height="20" Width="35" Margin="2,0"/>
<TextBox Visibility="{Binding TimeVisibility}" Text="{Binding Time}" ToolTip="زمان تمرینات" IsEnabled="{Binding TimeIsEnable}" Height="20" Width="35" Margin="2,0"/>
<ComboBox Tag="{Binding Name}" Visibility="{Binding LevelVisibility}" ItemsSource="{Binding Level}" IsEnabled="{Binding LevelIsEnable}" Foreground="{Binding BackgroundTextControl}" FontSize="15" Height="20" Width="70" Margin="2,0" ItemContainerStyle="{DynamicResource LevelBoxStyle}" SelectionChanged="ComboBox_SelectionChanged" SelectedIndex="0"/>
<CheckBox Visibility="{Binding CustomizeCbxVisibility}" IsChecked="{Binding IsChecked}" IsEnabled="{Binding CustomizeCbxIsEnable}" FontSize="15" VerticalAlignment="Center" Margin="2,0"/>
<ToggleButton Visibility="{Binding CustomizeBtnVisibility}" Content="سفارشی" IsEnabled="{Binding CustomizeBtnIsEnable}" FontSize="15" Margin="2,0" Style="{DynamicResource CustomizeStyle}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
SajjadKhati
یک شنبه 28 آذر 1400, 14:58 عصر
سلام
کد استایل تون چیه؟
یا نمونه پروژه شو بذارید تا چک شه .
elahe1393
یک شنبه 28 آذر 1400, 15:43 عصر
سلام
کد استایل تون چیه؟
یا نمونه پروژه شو بذارید تا چک شه .
ممنون بابت پاسخگوییتون
رنگها توی viewmodel مقداردهی شده چون با توجه به تم برنامه قابل تغییره
<Style x:Key="CustomizeStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle x:Name="ellipse" RadiusX="5" RadiusY="5" Width="50">
<Rectangle.ContextMenu>
<ContextMenu/>
</Rectangle.ContextMenu>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="{Binding BackgroundListLogin}" Offset="0.504"/>
<GradientStop Color="{Binding BackgroundListLogin}" Offset="1"/>
<GradientStop Color="{Binding BackgroundListLogin}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="سفارشی" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Foreground="{Binding BackgroundTextControl}"></TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.6"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LevelBoxStyle" TargetType="ComboBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Grid.Column="2" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={Re lativeSource TemplatedParent}}" >
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="5" Background="{Binding Background}" BorderBrush="{Binding BackgroundEnableControl}" BorderThickness="1" />
<Border Grid.Column="0" CornerRadius="5,0,0,5" Margin="1" Background="{Binding BackgroundListLogin}" BorderBrush="{Binding BackgroundRowListControl}" BorderThickness="0,0,1,0" />
<Path x:Name="Arrow" Grid.Column="1" Fill="{Binding BackgroundTextControl}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{Binding BackgroundMouseOverControl}" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{Binding BackgroundMouseOverControl}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3" />
<TextBox x:Name="PART_EditableTextBox" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="{Binding BackgroundListLogin}" />
<ScrollViewer SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
الان به این شکل ظاهر میشه
153620
درصورتیکه باید اینجوری باشه
153619
SajjadKhati
یک شنبه 28 آذر 1400, 16:31 عصر
ممنون بابت پاسخگوییتون
رنگها توی viewmodel مقداردهی شده چون با توجه به تم برنامه قابل تغییره
.
.
.
الان به این شکل ظاهر میشه
153620
درصورتیکه باید اینجوری باشه
153619
استایل با کلید CustomizeStyle تون را از نوع Button مشخص کردین . در صورتی که برای نوعِ ToggleButton بکار بردین که هیچ نوع رابطه ی پدر و فرزندی بین هم ندارن (رابطه ی ToggleButton و Button ، رابطه ی sibling یا خواهر و برادری هست) .
بنابراین اگه نمیخواین استایل با کلید CustomizeStyle را از نوع ToggleButton بگیرین ، حداقل باید از نوع ButtonBase بگیرین .
استایل با کلید LevelBoxStyle هم از نوع ComboBox گرفتین . در صورتی که این استایل را برای پروپرتیِ ItemContainerStyle ئه ComboBox بکار بردین . برای خودِ ComboBox بکار نبردین .
پروپرتیِ ItemContainerStyle هم استایلی هست که برای المنت های هر آیتم بکار میره .
یعنی در کمبوباکس ، برای ComboBoxItem بکار میره . نه برای خودِ ComboBox .
اگه میخواین استایل را برای کمبوباکس صرفا بکار ببرین ، کلید LevelBoxStyle را برای پروپرتیِ Style ئه ComboBox بکار ببرین .
------------
ضمنا ، ViewModel که جای تعیین مقادیر رنگ و اینها نیست .
رنگ و بِراش ، جزء وظایف View هست .
ViewModel صرفا ارتباط دهنده ی بین View با Model هست .
elahe1393
یک شنبه 28 آذر 1400, 17:35 عصر
سپاس از پاسخگوییتون
باتوجه به فرمایش شما تغییرات رو اعمال کردم ولی مشابه شکل زیر شد و دیگه کمبوباکس هم نمیشه باز کرد
153621
خوب از اونجایی که امکان داره رنگ با توجه به تم تغییر کنه بایند شده که این متغیرهایی که بایند میشن رو مگه نباید توی viewmodel تعریف کرد که بتونه تو view بایند بشه
SajjadKhati
یک شنبه 28 آذر 1400, 18:23 عصر
سپاس از پاسخگوییتون
باتوجه به فرمایش شما تغییرات رو اعمال کردم ولی مشابه شکل زیر شد و دیگه کمبوباکس هم نمیشه باز کرد
153621
خواهش میکنم .
پروژه تون را بذارید . همین جوری نمیشه نظر داد .
هر چند ContentPresenter را در تمپلیت نذاشتید ولی این مشکل انگار به این ربط نداشت .
Binding ها و چیزهای دیگه شاید مشکل داشته باشن .
خوب از اونجایی که امکان داره رنگ با توجه به تم تغییر کنه بایند شده که این متغیرهایی که بایند میشن رو مگه نباید توی viewmodel تعریف کرد که بتونه تو view بایند بشه
منظورتون از تم ، همون استایل هست دیگه؟
رنگ ها را که از منطق تجاری یا همون لایه ی Model نمیگیرید . میگیرید مگه؟ منطقی هم نیست که رنگ کنترل هاتون در لایه ی منطق تجاری تعریف بشه یا فرضا در دیتابیس ذخیره بشه .
فرضا دو تا استایل ئه Dark و Light دارید که با انتخاب شون ، یه مجموعه ای از استایل ها برای کنترل های مختلف ، تغییر میکنه دیگه . درسته؟
اگه این طوره ، خوب همون دو استایل را تعریف میکنید و در همون لایه ی View تغییر میدید دیگه .
elahe1393
یک شنبه 28 آذر 1400, 20:17 عصر
رنگهای هر بخش این view رو کاربر میتونه خودش انتخاب کنه رنگهارو پس از انتخاب کاربر ذخیره میکنم و به این view از طریق متغیرهایی که در viewmodel تعریف کردم که در ابتدای لود شدن فرم مقداردهی شده پاس میدهم
قبل از اینکه درخت رو به این صورت تعریف کنم یعنی هر شاخه رو خودم تعریف میکردم که چه نامهایی بگیره این استایلها روی کنترلها درست کار میکرد مثل نمونه درستی که نشان دادم ولی وقتی آیتم درخت رو به صورت HierarchicalDataTemplate تعریف کردم الان به این شکل که در آخر نشون دادم نمایش داده میشه
الان رفتم همه متغیرهای رنگ در استایلهارو کد رنگ وارد کردم درست نشون میده پیشنهاد شما چیه که بتونم رنگهایی که کاربر تعیین کرده رو اینجا مقداردهی کنم؟ یعنی بایندهای این رنگها در استایل چطور باید باشه؟
elahe1393
یک شنبه 28 آذر 1400, 20:28 عصر
یه سوال دسگه اس هم داشتم اینکه وقتی مقادیر یه شاخه درخت رو در کد عوض میکنیم و treeview.items.refresh اعمال میشه کل درخت بسته مشه اگر بخوام فقط اون شاخه ای که تغییر کرده رفرش بشه چه باید بکنم؟
SajjadKhati
یک شنبه 28 آذر 1400, 22:32 عصر
رنگهای هر بخش این view رو کاربر میتونه خودش انتخاب کنه رنگهارو پس از انتخاب کاربر ذخیره میکنم و به این view از طریق متغیرهایی که در viewmodel تعریف کردم که در ابتدای لود شدن فرم مقداردهی شده پاس میدهم
اول اینکه انتخاب کردنِ رنگِ هر قسمت از یک المنت و کنترل توسط کاربر نهایی ، کار چندان جالبی به نظر نمیرسه .
همونطور که خیلی از نرم افزارهای مهم ، این طور عمل نمیکنن .
اغلب ، دو یا چند تا استایل تعریف میکنن تا کاربر بین این استایل ها ، هر کدوم را اگه خواست ، انتخاب کنه .
نهایتا فرضا رنگ یک یا چند کنترل خاص را میذارن تا کاربر انتخاب کنه (که اون هم توی نرم افزارهای محدودی هست) .
به هر حال ، وظیفه ی ViewModel ، تعریفِ متغییری برای ذخیره ی رنگ نیست . ViewModel ، فقط واسطه ی بین View با Model هست . وظایفی را انجام میده که مربوط به ارتباط برقرار کردن بین View با Model باشه . نه کار اضافی دیگه ای .
ذخیره ی مقدار رنگی که کاربر انتخاب کرده ، اگه توی دیتابیس ذخیره میکنین ، وظیفه ی Model هست (البته با ساختار برنامه تون آشنا نیستم و میتونه متفاوت باشه) .
برای Binding هم میتونید از طریق ViewModel ، به Model و اعضاش ، Binding را انجام بدین .
یعنی توسط Binding ، پروپرتی ای در View تون را از طریق شیِ ViewModel ، به پروپرتی ای که در Model تعریف کردید ، متصل یا همون Binding کنید .
----------
نمونه پروژه ی تغییر استایل ای را در آخر این پست پیوست میکنم که میتونید با انتخاب کمبوباکسی که وجود داره ، استایل ها را تغییر بدین .
همچنین نمونه پروژه ی MVVM را هم از لینک زیر میتونید ببینید :
https://barnamenevis.org/showthread.php?566867-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%D9%86%D9%85%D9%88%D9%86%D9%87-%D9%BE%D8%B1%D9%88%DA%98%D9%87-%DB%8C-MVVM-%D8%AF%D8%B1-WPF&p=2444904&viewfull=1#post2444904
قبل از اینکه درخت رو به این صورت تعریف کنم یعنی هر شاخه رو خودم تعریف میکردم که چه نامهایی بگیره این استایلها روی کنترلها درست کار میکرد مثل نمونه درستی که نشان دادم ولی وقتی آیتم درخت رو به صورت HierarchicalDataTemplate تعریف کردم الان به این شکل که در آخر نشون دادم نمایش داده میشه
الان رفتم همه متغیرهای رنگ در استایلهارو کد رنگ وارد کردم درست نشون میده پیشنهاد شما چیه که بتونم رنگهایی که کاربر تعیین کرده رو اینجا مقداردهی کنم؟ یعنی بایندهای این رنگها در استایل چطور باید باشه؟
همونطور که در بالا توضیح داده شد ، اگه رنگ ها در دیتابیس ذخیره میشن ، به نظر میرسه که متغییرهای مربوط به رنگ بهتره که در Model تعریف بشن (مگر اینکه ساختار برنامه تون جوری باشه که ندونم و به نظرتون بهتر برسه که در View تعریف بشن) .
به هر حال ، ViewModel جایی نیست که متغییر مربوط به رنگ را در اون تعریف کنید .
بعد هم پروپرتی مورد نظر در View را توسط ViewModel ، به پروپرتیِ مربوط به رنگ که در Model ذخیره شده بود ، Binding میکنید (مثلِ Binding ای که به پروپرتیِ Student.FirstName در پروپرتیِ Text ئه TextBox در خط 27 در MainWindow.xaml در پروژه ای که در لینک بالا داده شد ، هست) .
یه سوال دسگه اس هم داشتم اینکه وقتی مقادیر یه شاخه درخت رو در کد عوض میکنیم و treeview.items.refresh اعمال میشه کل درخت بسته مشه اگر بخوام فقط اون شاخه ای که تغییر کرده رفرش بشه چه باید بکنم؟
TreeView کار نکردم .
برای ریفرش کردن یک قسمت و آیتم های خاص ، نمیدونم .
elahe1393
دوشنبه 29 آذر 1400, 14:30 عصر
سلام سپاس از راهنمایی هاتون موفق باشید
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.